Update the main branch and add the following changes:

 - update all SPs to support and use FF-A v1.1
 - update the project to support Armv8.5-A Branch Protection feature.
 - add a new FWU agent implementation, which implements a PSA Certified
   Firmware Update API 1.0 client. This allows implementing an FWU proxy
   on A+M systems.
 - add a new shared library called "libpsats" to help integrating the
   PSA clients to 3rd party linux user-space projects

For more details please refer to the change log.

Change-Id: I6baed8c340bfe47a019f870df0d543bb8e4da543
Signed-off-by: Gyorgy Szing <gyorgy.szing@arm.com>
diff --git a/.checkpatch b/.checkpatch
index dd8dad9..4d69058 100644
--- a/.checkpatch
+++ b/.checkpatch
@@ -7,6 +7,8 @@
 
 --showfile
 --codespell
+# Please set CODESPELL_FILE in the environment.
+--codespellfile="$CODESPELL_FILE"
 --ignore SPDX_LICENSE_TAG,PREFER_KERNEL_TYPES,USLEEP_RANGE,GERRIT_CHANGE_ID,FILE_PATH_CHANGES,UNNECESSARY_PARENTHESES,PREFER_DEFINED_ATTRIBUTE_MACRO,BIT_MACRO
 --no-tree
 --terse
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
index a33d90c..6aea12d 100644
--- a/.readthedocs.yaml
+++ b/.readthedocs.yaml
@@ -12,6 +12,10 @@
     python: "3.8"
   apt_packages:
     - plantuml
+    - wget
+  jobs:
+    post_install:
+        - wget https://github.com/plantuml/plantuml/releases/download/v1.2024.7/plantuml-1.2024.7.jar -O $HOME/plantuml.jar
 
 # Build documentation in the docs/ directory with Sphinx
 sphinx:
@@ -20,4 +24,4 @@
 # Optionally declare the Python requirements required to build your docs
 python:
    install:
-   - requirements: docs/requirements.txt
\ No newline at end of file
+   - requirements: docs/requirements.txt
diff --git a/components/app/fwu-tool/app/fwu_app.cpp b/components/app/fwu-tool/app/fwu_app.cpp
index 173afce..9613e73 100644
--- a/components/app/fwu-tool/app/fwu_app.cpp
+++ b/components/app/fwu-tool/app/fwu_app.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -31,13 +31,12 @@
 	: m_update_agent()
 	, m_fw_store()
 {
-	memset(&m_update_agent, 0, sizeof(m_update_agent));
 	memset(&m_fw_store, 0, sizeof(m_fw_store));
 }
 
 fwu_app::~fwu_app()
 {
-	update_agent_deinit(&m_update_agent);
+	update_agent_deinit(m_update_agent);
 	banked_fw_store_deinit(&m_fw_store);
 
 	fwu_deconfigure();
@@ -96,10 +95,9 @@
 		return -1;
 	}
 
-	status = update_agent_init(&m_update_agent, boot_index, direct_fw_inspector_inspect,
-				   &m_fw_store);
+	m_update_agent = update_agent_init(boot_index, direct_fw_inspector_inspect, &m_fw_store);
 
-	if (status) {
+	if (!m_update_agent) {
 		IMSG("update agent initialisation error %d", status);
 		return -1;
 	}
@@ -111,27 +109,31 @@
 int fwu_app::update_image(const struct uuid_octets &img_type_uuid, const uint8_t *img_data,
 			  size_t img_size)
 {
-	int status = update_agent_begin_staging(&m_update_agent);
+	int status = update_agent_begin_staging(m_update_agent, 0, 0, NULL);
 
 	if (status)
 		return status;
 
 	uint32_t stream_handle = 0;
+	uint32_t progress = 0;
+	uint32_t total_work = 0;
 
-	status = update_agent_open(&m_update_agent, &img_type_uuid, &stream_handle);
+	status = update_agent_open(m_update_agent, &img_type_uuid, FWU_OP_TYPE_WRITE,
+				   &stream_handle);
 
 	if (!status) {
-		status = update_agent_write_stream(&m_update_agent, stream_handle, img_data,
+		status = update_agent_write_stream(m_update_agent, stream_handle, img_data,
 						   img_size);
 
 		if (!status)
-			status = update_agent_commit(&m_update_agent, stream_handle, false);
+			status = update_agent_commit(m_update_agent, stream_handle, false, 0,
+						     &progress, &total_work);
 	}
 
 	if (!status)
-		status = update_agent_end_staging(&m_update_agent);
+		status = update_agent_end_staging(m_update_agent);
 	else
-		update_agent_cancel_staging(&m_update_agent);
+		update_agent_cancel_staging(m_update_agent);
 
 	return status;
 }
@@ -139,7 +141,8 @@
 int fwu_app::read_object(const struct uuid_octets &object_uuid, std::vector<uint8_t> &data)
 {
 	uint32_t stream_handle = 0;
-	int status = update_agent_open(&m_update_agent, &object_uuid, &stream_handle);
+	int status = update_agent_open(m_update_agent, &object_uuid, FWU_OP_TYPE_READ,
+				       &stream_handle);
 
 	if (status)
 		return status;
@@ -150,6 +153,8 @@
 	size_t reported_total_len = 0;
 	size_t read_so_far = 0;
 	size_t vector_capacity = 512;
+	uint32_t progress = 0;
+	uint32_t total_work = 0;
 
 	data.resize(vector_capacity);
 
@@ -157,7 +162,7 @@
 		size_t data_len_read = 0;
 		size_t requested_read_len = vector_capacity - read_so_far;
 
-		status = update_agent_read_stream(&m_update_agent, stream_handle,
+		status = update_agent_read_stream(m_update_agent, stream_handle,
 						  &data[read_so_far], requested_read_len,
 						  &data_len_read, &reported_total_len);
 
@@ -181,14 +186,15 @@
 
 	} while (!status);
 
-	status = update_agent_commit(&m_update_agent, stream_handle, false);
+	status = update_agent_commit(m_update_agent, stream_handle, false, 0, &progress,
+				     &total_work);
 
 	return status;
 }
 
 struct update_agent *fwu_app::update_agent()
 {
-	return &m_update_agent;
+	return m_update_agent;
 }
 
 const struct metadata_serializer *fwu_app::select_metadata_serializer(unsigned int version)
diff --git a/components/app/fwu-tool/app/fwu_app.h b/components/app/fwu-tool/app/fwu_app.h
index 8bbaa9d..c60f192 100644
--- a/components/app/fwu-tool/app/fwu_app.h
+++ b/components/app/fwu-tool/app/fwu_app.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -11,7 +11,7 @@
 #include <vector>
 
 #include "common/uuid/uuid.h"
-#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
 #include "service/fwu/fw_store/banked/banked_fw_store.h"
 
 /*
@@ -98,7 +98,7 @@
 
 	static const struct metadata_serializer *select_metadata_serializer(unsigned int version);
 
-	struct update_agent m_update_agent;
+	struct update_agent *m_update_agent;
 	struct fw_store m_fw_store;
 };
 
diff --git a/components/app/fwu-tool/app/metadata_v1_reader.cpp b/components/app/fwu-tool/app/metadata_v1_reader.cpp
index 195fa6e..4394050 100644
--- a/components/app/fwu-tool/app/metadata_v1_reader.cpp
+++ b/components/app/fwu-tool/app/metadata_v1_reader.cpp
@@ -7,7 +7,7 @@
 #include <assert.h>
 
 #include "metadata_reader.h"
-#include "protocols/service/fwu/packed-c/metadata_v1.h"
+#include "protocols/service/fwu/metadata_v1.h"
 
 class metadata_v1_reader : public metadata_version_specific_reader {
 public:
diff --git a/components/app/fwu-tool/app/metadata_v2_reader.cpp b/components/app/fwu-tool/app/metadata_v2_reader.cpp
index 61faa61..9ce3393 100644
--- a/components/app/fwu-tool/app/metadata_v2_reader.cpp
+++ b/components/app/fwu-tool/app/metadata_v2_reader.cpp
@@ -7,7 +7,7 @@
 #include <assert.h>
 
 #include "metadata_reader.h"
-#include "protocols/service/fwu/packed-c/metadata_v2.h"
+#include "protocols/service/fwu/metadata_v2.h"
 
 class metadata_v2_reader : public metadata_version_specific_reader {
 public:
diff --git a/components/app/fwu-tool/cmd_print_image_dir.cpp b/components/app/fwu-tool/cmd_print_image_dir.cpp
index 1e07027..a50af82 100644
--- a/components/app/fwu-tool/cmd_print_image_dir.cpp
+++ b/components/app/fwu-tool/cmd_print_image_dir.cpp
@@ -13,7 +13,7 @@
 
 #include "common/uuid/uuid.h"
 #include "print_uuid.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
+#include "protocols/service/fwu/fwu_proto.h"
 
 void cmd_print_image_dir(fwu_app &app)
 {
@@ -29,13 +29,13 @@
 		return;
 	}
 
-	if (fetched_object.size() < offsetof(ts_fwu_image_directory, img_info_entry)) {
+	if (fetched_object.size() < offsetof(fwu_image_directory, img_info_entry)) {
 		printf("Error: invalid image directory size\n");
 		return;
 	}
 
-	const struct ts_fwu_image_directory *img_dir =
-		(const struct ts_fwu_image_directory *)fetched_object.data();
+	const struct fwu_image_directory *img_dir =
+		(const struct fwu_image_directory *)fetched_object.data();
 
 	printf("\nimage_directory (size %zu bytes) :\n", fetched_object.size());
 	printf("\tdirectory_version : %d\n", img_dir->directory_version);
diff --git a/components/app/fwu-tool/cmd_print_metadata_v1.cpp b/components/app/fwu-tool/cmd_print_metadata_v1.cpp
index 6539e57..0fcfe45 100644
--- a/components/app/fwu-tool/cmd_print_metadata_v1.cpp
+++ b/components/app/fwu-tool/cmd_print_metadata_v1.cpp
@@ -13,8 +13,8 @@
 
 #include "common/uuid/uuid.h"
 #include "print_uuid.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
-#include "protocols/service/fwu/packed-c/metadata_v1.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "protocols/service/fwu/metadata_v1.h"
 
 void cmd_print_metadata_v1(fwu_app &app)
 {
diff --git a/components/app/fwu-tool/cmd_print_metadata_v2.cpp b/components/app/fwu-tool/cmd_print_metadata_v2.cpp
index 69e09d7..7367438 100644
--- a/components/app/fwu-tool/cmd_print_metadata_v2.cpp
+++ b/components/app/fwu-tool/cmd_print_metadata_v2.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -13,8 +13,8 @@
 
 #include "common/uuid/uuid.h"
 #include "print_uuid.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
-#include "protocols/service/fwu/packed-c/metadata_v2.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "protocols/service/fwu/metadata_v2.h"
 
 void cmd_print_metadata_v2(fwu_app &app)
 {
@@ -42,15 +42,15 @@
 	printf("\tcrc_32 : 0x%x\n", metadata->crc_32);
 	printf("\tversion : %d\n", metadata->version);
 	printf("\tmetadata_size : %d\n", metadata->metadata_size);
-	printf("\theader_size : %d\n", metadata->header_size);
+	printf("\tdescriptor_offset : %d\n", metadata->descriptor_offset);
 	printf("\tactive_index : %d\n", metadata->active_index);
 	printf("\tprevious_active_index : %d\n", metadata->previous_active_index);
 	printf("\tbank_state : 0x%x 0x%x\n", metadata->bank_state[0], metadata->bank_state[1]);
 
-	if (metadata->metadata_size <= metadata->header_size)
+	if (metadata->metadata_size <= metadata->descriptor_offset)
 		return;
 
-	size_t fw_store_desc_size = metadata->metadata_size - metadata->header_size;
+	size_t fw_store_desc_size = metadata->metadata_size - metadata->descriptor_offset;
 
 	if (fw_store_desc_size < sizeof(fwu_fw_store_desc)) {
 		printf("\tInsufficient space for fw store descriptor\n");
@@ -59,13 +59,13 @@
 
 	/* Print optional fw store descriptor */
 	struct fwu_fw_store_desc *fw_store_desc =
-		(struct fwu_fw_store_desc *)&fetched_object[metadata->header_size];
+		(struct fwu_fw_store_desc *)&fetched_object[metadata->descriptor_offset];
 
 	printf("\tfw_store_desc :\n");
 	printf("\t\tnum_banks : %d\n", fw_store_desc->num_banks);
 	printf("\t\tnum_images : %d\n", fw_store_desc->num_images);
 	printf("\t\timg_entry_size : %d\n", fw_store_desc->img_entry_size);
-	printf("\t\tbank_entry_size : %d\n", fw_store_desc->bank_entry_size);
+	printf("\t\tbank_info_entry_size : %d\n", fw_store_desc->bank_info_entry_size);
 
 	for (unsigned int i = 0; i < fw_store_desc->num_images; i++) {
 		struct fwu_image_entry *img_entry = &fw_store_desc->img_entry[i];
diff --git a/components/app/platform-inspect/attest_report_fetcher.cpp b/components/app/platform-inspect/attest_report_fetcher.cpp
index 33977b5..09871c1 100644
--- a/components/app/platform-inspect/attest_report_fetcher.cpp
+++ b/components/app/platform-inspect/attest_report_fetcher.cpp
@@ -1,173 +1,120 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <cstring>
-#include <string>
-#include <vector>
-#include <service/attestation/client/psa/iat_client.h>
-#include <service/attestation/client/provision/attest_provision_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include <service_locator.h>
-#include <psa/crypto.h>
-#include <psa/initial_attestation.h>
 #include <provision/attest_provision.h>
 #include <qcbor/qcbor_spiffy_decode.h>
+#include <string>
 #include <t_cose/t_cose_sign1_verify.h>
+#include <vector>
 
-static bool fetch_and_verify(std::vector<uint8_t> &report, std::string &error_msg);
+#include "libpsats.h"
+
 static bool fetch_iak_public_key(psa_key_id_t &iak_id, std::string &error_msg);
 static bool verify_token(std::vector<uint8_t> &report, const uint8_t *token, size_t token_len,
-    psa_key_id_t iak_id, std::string &error_msg);
+			 psa_key_id_t iak_id, std::string &error_msg);
 
-bool fetch_attest_report(std::vector<uint8_t> &report, std::string &error_msg)
+bool fetch_and_verify(std::vector<uint8_t> &report, std::string &error_msg)
 {
-    bool success = false;
-    struct rpc_caller_session *rpc_session = NULL;
-    struct service_context *attest_service_context = NULL;
+	bool result = true;
+	uint8_t token_buf[PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE];
+	uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32];
+	psa_key_id_t iak_id;
+	int status;
 
-    attest_service_context =
-        service_locator_query("sn:trustedfirmware.org:attestation:0");
+	if (!fetch_iak_public_key(iak_id, error_msg)) {
+		return false;
+	}
 
-    if (attest_service_context) {
+	status = psa_generate_random(challenge, sizeof(challenge));
 
-        rpc_session = service_context_open(attest_service_context);
+	if (status != PSA_SUCCESS) {
+		error_msg = "Failed to generate challenge";
+		result = false;
+	}
 
-        if (rpc_session) {
+	if (result) {
+		size_t token_size;
 
-            psa_iat_client_init(rpc_session);
-            attest_provision_client_init(rpc_session);
+		status = psa_initial_attest_get_token(challenge, sizeof(challenge), token_buf,
+						      sizeof(token_buf), &token_size);
 
-            success = fetch_and_verify(report, error_msg);
-        }
-        else {
+		if (status == PSA_SUCCESS) {
+			result = verify_token(report, token_buf, token_size, iak_id, error_msg);
+		} else {
+			error_msg = "Failed to fetch attestation token";
+		}
+	}
 
-            error_msg = "Failed to open RPC session";
-        }
-    }
-    else {
+	psa_destroy_key(iak_id);
 
-        error_msg = "Failed to discover attestation service provider";
-    }
-
-    /* Clean-up context */
-    psa_iat_client_deinit();
-    attest_provision_client_deinit();
-    service_context_close(attest_service_context, rpc_session);
-    service_context_relinquish(attest_service_context);
-
-    return success;
-}
-
-static bool fetch_and_verify(std::vector<uint8_t> &report, std::string &error_msg)
-{
-    bool success = false;
-    uint8_t token_buf[PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE];
-    uint8_t challenge[PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32];
-    psa_key_id_t iak_id;
-    int status;
-
-    if (!fetch_iak_public_key(iak_id, error_msg)) {
-
-        return false;
-    }
-
-    status = psa_generate_random(challenge, sizeof(challenge));
-
-    if (status != PSA_SUCCESS) {
-
-        error_msg = "Failed to generate challenge";
-        return false;
-    }
-
-    size_t token_size;
-
-    status =
-        psa_initial_attest_get_token(challenge, sizeof(challenge),
-            token_buf, sizeof(token_buf), &token_size);
-
-    if (status == PSA_SUCCESS) {
-
-        success = verify_token(report, token_buf, token_size, iak_id, error_msg);
-    }
-    else {
-
-        error_msg = "Failed to fetch attestation token";
-    }
-
-    return success;
+	return result;
 }
 
 static bool fetch_iak_public_key(psa_key_id_t &iak_id, std::string &error_msg)
 {
-    size_t iak_pub_key_len = 0;
-    uint8_t iak_pub_key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
+	size_t iak_pub_key_len = 0;
+	uint8_t iak_pub_key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
 
-    int status = attest_provision_export_iak_public_key(iak_pub_key_buf,
-        sizeof(iak_pub_key_buf), &iak_pub_key_len);
+	int status = attest_provision_export_iak_public_key(
+		iak_pub_key_buf, sizeof(iak_pub_key_buf), &iak_pub_key_len);
 
-    if (status == PSA_SUCCESS) {
+	if (status == PSA_SUCCESS) {
+		psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
 
-        psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+		psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
+		psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
 
-        psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
-        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH);
+		psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
+		psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
+		psa_set_key_bits(&attributes, 256);
 
-        psa_set_key_algorithm(&attributes, PSA_ALG_ECDSA(PSA_ALG_SHA_256));
-        psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
-        psa_set_key_bits(&attributes, 256);
+		status = psa_import_key(&attributes, iak_pub_key_buf, iak_pub_key_len, &iak_id);
 
-        status = psa_import_key(&attributes, iak_pub_key_buf, iak_pub_key_len, &iak_id);
+		if (status != PSA_SUCCESS) {
+			printf("psa_import_key status: %d\n", status);
+			error_msg = "Failed to set-up IAK for verify";
+		}
 
-        if (status != PSA_SUCCESS) {
+		psa_reset_key_attributes(&attributes);
+	} else {
+		error_msg = "Failed to export IAK public key";
+	}
 
-            printf("psa_import_key status: %d\n", status);
-            error_msg = "Failed to set-up IAK for verify";
-        }
-
-        psa_reset_key_attributes(&attributes);
-    }
-    else {
-
-        error_msg = "Failed to export IAK public key";
-    }
-
-    return (status == PSA_SUCCESS);
+	return (status == PSA_SUCCESS);
 }
 
 static bool verify_token(std::vector<uint8_t> &report, const uint8_t *token, size_t token_len,
-    psa_key_id_t iak_id, std::string &error_msg)
+			 psa_key_id_t iak_id, std::string &error_msg)
 {
-    struct t_cose_sign1_verify_ctx verify_ctx;
-    struct t_cose_key key_pair;
+	struct t_cose_sign1_verify_ctx verify_ctx;
+	struct t_cose_key key_pair;
 
-    key_pair.k.key_handle = iak_id;
-    key_pair.crypto_lib = T_COSE_CRYPTO_LIB_PSA;
-    UsefulBufC signed_cose;
-    UsefulBufC report_body;
+	key_pair.k.key_handle = iak_id;
+	key_pair.crypto_lib = T_COSE_CRYPTO_LIB_PSA;
+	UsefulBufC signed_cose;
+	UsefulBufC report_body;
 
-    signed_cose.ptr = token;
-    signed_cose.len = token_len;
+	signed_cose.ptr = token;
+	signed_cose.len = token_len;
 
-    report_body.ptr = NULL;
-    report_body.len = 0;
+	report_body.ptr = NULL;
+	report_body.len = 0;
 
-    t_cose_sign1_verify_init(&verify_ctx, 0);
-    t_cose_sign1_set_verification_key(&verify_ctx, key_pair);
+	t_cose_sign1_verify_init(&verify_ctx, 0);
+	t_cose_sign1_set_verification_key(&verify_ctx, key_pair);
 
-    int status = t_cose_sign1_verify(&verify_ctx, signed_cose, &report_body, NULL);
+	int status = t_cose_sign1_verify(&verify_ctx, signed_cose, &report_body, NULL);
 
-    if (status == T_COSE_SUCCESS) {
+	if (status == T_COSE_SUCCESS) {
+		report.resize(report_body.len);
+		memcpy(report.data(), report_body.ptr, report_body.len);
+	} else {
+		error_msg = "Attestation token failed to verify";
+	}
 
-        report.resize(report_body.len);
-        memcpy(report.data(), report_body.ptr, report_body.len);
-    }
-    else {
-
-        error_msg = "Attestation token failed to verify";
-    }
-
-    return (status == T_COSE_SUCCESS);
+	return (status == T_COSE_SUCCESS);
 }
diff --git a/components/app/platform-inspect/attest_report_fetcher.h b/components/app/platform-inspect/attest_report_fetcher.h
index 75d171b..51eaed6 100644
--- a/components/app/platform-inspect/attest_report_fetcher.h
+++ b/components/app/platform-inspect/attest_report_fetcher.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,9 +7,9 @@
 #ifndef ATTEST_REPORT_FETCHER_H
 #define ATTEST_REPORT_FETCHER_H
 
+#include <cstdint>
 #include <string>
 #include <vector>
-#include <cstdint>
 
 /** \brief Fetch and verify an attestaton report
  *
@@ -18,7 +18,6 @@
  *
  * \return Returns true if fetch successful
  */
-bool fetch_attest_report(std::vector<uint8_t> &report, std::string &error_msg);
-
+bool fetch_and_verify(std::vector<uint8_t> &report, std::string &error_msg);
 
 #endif /* ATTEST_REPORT_FETCHER_H */
diff --git a/components/app/platform-inspect/component.cmake b/components/app/platform-inspect/component.cmake
index 07200a9..d948657 100644
--- a/components/app/platform-inspect/component.cmake
+++ b/components/app/platform-inspect/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
diff --git a/components/app/platform-inspect/platform_inspect.cpp b/components/app/platform-inspect/platform_inspect.cpp
index 93c8f88..ae1330b 100644
--- a/components/app/platform-inspect/platform_inspect.cpp
+++ b/components/app/platform-inspect/platform_inspect.cpp
@@ -1,45 +1,52 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <cstdint>
 #include <cstdio>
+#include <service/attestation/reporter/dump/pretty/pretty_report_dump.h>
 #include <string>
 #include <vector>
-#include <psa/crypto.h>
-#include <service_locator.h>
-#include <service/attestation/reporter/dump/raw/raw_report_dump.h>
-#include <service/attestation/reporter/dump/pretty/pretty_report_dump.h>
+
 #include "attest_report_fetcher.h"
+#include "libpsats.h"
 
-int main(int argc, char *argv[])
+int main(void)
 {
-    int rval = -1;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	int rval = -1;
+	std::string error_msg;
+	std::vector<uint8_t> attest_report;
 
-    psa_status_t psa_status = psa_crypto_init();
+	psa_status = libpsats_init_crypto_context("sn:trustedfirmware.org:crypto:0");
+	if (psa_status) {
+		printf("libpsats_init_crypto_context failed: %d\n", psa_status);
+		goto cleanup;
+	}
 
-    if (psa_status != PSA_SUCCESS) {
+	psa_status = libpsats_init_attestation_context("sn:trustedfirmware.org:attestation:0");
+	if (psa_status) {
+		printf("libpsats_init_crypto_context failed: %d\n", psa_status);
+		goto cleanup;
+	}
 
-        printf("psa_crypto_init failed: %d\n", psa_status);
-        return rval;
-    }
+	psa_status = psa_crypto_init();
+	if (psa_status) {
+		printf("psa_crypto_init failed: %d\n", psa_status);
+		goto cleanup;
+	}
 
-    service_locator_init();
+	/* Fetch platform info */
+	if (fetch_and_verify(attest_report, error_msg))
+		rval = pretty_report_dump(attest_report.data(), attest_report.size());
+	else
+		printf("%s\n", error_msg.c_str());
 
-    /* Fetch platform info */
-    std::string error_msg;
-    std::vector<uint8_t> attest_report;
+cleanup:
+	libpsats_deinit_crypto_context();
+	libpsats_deinit_attestation_context();
 
-    if (fetch_attest_report(attest_report, error_msg)) {
-
-        rval = pretty_report_dump(attest_report.data(), attest_report.size());
-    }
-    else {
-
-        printf("%s\n", error_msg.c_str());
-    }
-
-    return rval;
+	return rval;
 }
diff --git a/components/app/ts-demo/component.cmake b/components/app/ts-demo/component.cmake
index c4a7392..fe0f5fa 100644
--- a/components/app/ts-demo/component.cmake
+++ b/components/app/ts-demo/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,6 +9,6 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ts-demo.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/ts-demo.c"
 	)
 
diff --git a/components/app/ts-demo/test/ts-demo_tests.cpp b/components/app/ts-demo/test/ts-demo_tests.cpp
index e78f8a2..7fd104f 100644
--- a/components/app/ts-demo/test/ts-demo_tests.cpp
+++ b/components/app/ts-demo/test/ts-demo_tests.cpp
@@ -1,59 +1,62 @@
 /*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <app/ts-demo/ts-demo.h>
-#include <service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
 #include <CppUTest/TestHarness.h>
-#include <service_locator.h>
+#include <app/ts-demo/ts-demo.h>
+#include <protocols/rpc/common/packed-c/encoding.h>
 #include <service/crypto/client/cpp/crypto_client.h>
+#include <service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h>
+#include <service/crypto/client/psa/psa_crypto_client.h>
+#include <service_locator.h>
 
+TEST_GROUP(TsDemoTests)
+{
+	void setup()
+	{
+		m_rpc_session = NULL;
+		m_crypto_service_context = NULL;
+		m_crypto_client = NULL;
 
-TEST_GROUP(TsDemoTests) {
+		service_locator_init();
 
-    void setup()
-    {
-        m_rpc_session = NULL;
-        m_crypto_service_context = NULL;
-        m_crypto_client = NULL;
+		m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
+		CHECK(m_crypto_service_context);
 
-        service_locator_init();
+		m_rpc_session = service_context_open(m_crypto_service_context);
+		CHECK(m_rpc_session);
 
-        m_crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
-        CHECK(m_crypto_service_context);
+		(void)psa_crypto_client_init(m_rpc_session);
 
-        m_rpc_session = service_context_open(m_crypto_service_context);
-        CHECK(m_rpc_session);
-
-        m_crypto_client = new packedc_crypto_client(m_rpc_session);
-    }
-
-    void teardown()
-    {
-        delete m_crypto_client;
-        m_crypto_client = NULL;
-
-	if (m_crypto_service_context) {
-	        if (m_rpc_session) {
-                        service_context_close(m_crypto_service_context, m_rpc_session);
-                        m_rpc_session = NULL;
-	        }
-
-                service_context_relinquish(m_crypto_service_context);
-                m_crypto_service_context = NULL;
+		m_crypto_client = new packedc_crypto_client(m_rpc_session);
 	}
-    }
 
-    struct rpc_caller_session *m_rpc_session;
-    struct service_context *m_crypto_service_context;
-    crypto_client *m_crypto_client;
+	void teardown()
+	{
+		delete m_crypto_client;
+		m_crypto_client = NULL;
+
+		if (m_crypto_service_context) {
+			if (m_rpc_session) {
+				service_context_close(m_crypto_service_context, m_rpc_session);
+				m_rpc_session = NULL;
+			}
+
+			psa_crypto_client_deinit();
+			service_context_relinquish(m_crypto_service_context);
+			m_crypto_service_context = NULL;
+		}
+	}
+
+	struct rpc_caller_session *m_rpc_session;
+	struct service_context *m_crypto_service_context;
+	crypto_client *m_crypto_client;
 };
 
 TEST(TsDemoTests, runTsDemo)
 {
-    int status = run_ts_demo(m_crypto_client, false);
-    CHECK_EQUAL(0, status);
+	int status = run_ts_demo(false);
+	CHECK_EQUAL(0, status);
 }
diff --git a/components/app/ts-demo/ts-demo.c b/components/app/ts-demo/ts-demo.c
new file mode 100644
index 0000000..43b3adb
--- /dev/null
+++ b/components/app/ts-demo/ts-demo.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "ts-demo.h"
+
+#include <psa/crypto.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static const psa_key_id_t SIGNING_KEY_ID = 0x100;
+static const psa_key_id_t ENCRYPTION_KEY_ID = 0x101;
+
+bool m_verbose = true;
+
+void print_intro(void)
+{
+	if (m_verbose) {
+		printf("\nDemonstrates use of trusted services from an application");
+		printf("\n---------------------------------------------------------");
+		printf("\nA client requests a set of crypto operations performed by");
+		printf("\nthe Crypto service.  Key storage for persistent keys is");
+		printf("\nprovided by the Secure Storage service via the ITS client.\n");
+		printf("\n");
+	}
+}
+
+void wait(int seconds)
+{
+	if (m_verbose)
+		sleep(seconds);
+}
+
+void print_status(psa_status_t status)
+{
+	if (m_verbose) {
+		if (status == PSA_SUCCESS)
+			printf("\n\tOperation successful\n");
+		else
+			printf("\n\tOperation failed. op error: %d\n", status);
+	}
+}
+
+void print_byte_array(const uint8_t *array, size_t len)
+{
+	size_t count = 0;
+	size_t column = 0;
+
+	while (count < len) {
+		if (column == 0)
+			printf("\n\t\t");
+		else
+			printf(" ");
+
+		printf("%02X", array[count]);
+
+		++count;
+		column = (column + 1) % 8;
+	}
+
+	printf("\n");
+}
+
+bool generate_signing_key(psa_key_id_t *signing_key_id)
+{
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+	psa_set_key_id(&attributes, SIGNING_KEY_ID);
+	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
+	psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
+	psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
+	psa_set_key_bits(&attributes, 256);
+
+	if (m_verbose)
+		printf("Generating ECC signing key");
+
+	status = psa_generate_key(&attributes, signing_key_id);
+	psa_reset_key_attributes(&attributes);
+
+	print_status(status);
+
+	return (status != PSA_SUCCESS);
+}
+
+bool sign_and_verify_message(const char *message, psa_key_id_t signing_key_id)
+{
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+	bool error = false;
+	uint8_t message_buffer[100];
+	size_t message_len = strlen(message) + 1;
+
+	if (message_len > sizeof(message_buffer))
+		message_len = sizeof(message_buffer) - 1;
+
+	memset(message_buffer, 0, sizeof(message_buffer));
+	memcpy(message_buffer, message, message_len);
+
+	/* Sign message */
+	uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
+	size_t signature_length;
+
+	if (m_verbose)
+		printf("Signing message: \"%s\" using key: %d", message_buffer, signing_key_id);
+
+	status = psa_sign_hash(signing_key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256),
+			       message_buffer, message_len, signature, sizeof(signature),
+			       &signature_length);
+
+	print_status(status);
+
+	if (m_verbose && (status == PSA_SUCCESS)) {
+		printf("\tSignature bytes: ");
+		print_byte_array(signature, signature_length);
+	}
+
+	error |= (status != PSA_SUCCESS);
+
+	/* Verify signature against original message */
+	if (m_verbose)
+		printf("Verify signature using original message: \"%s\"", message_buffer);
+
+	status = psa_verify_hash(signing_key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256),
+				 message_buffer, message_len, signature, signature_length);
+
+	print_status(status);
+
+	error |= (status != PSA_SUCCESS);
+
+	/* Verify signature against modified message */
+	message_buffer[0] = '!';
+	if (m_verbose)
+		printf("Verify signature using modified message: \"%s\"", message_buffer);
+
+	status = psa_verify_hash(signing_key_id, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256),
+				 message_buffer, message_len, signature, signature_length);
+
+	if (status == PSA_ERROR_INVALID_SIGNATURE) {
+		if (m_verbose)
+			printf("\n\tSuccessfully detected modified message\n");
+	} else {
+		print_status(status);
+	}
+
+	error |= (status == PSA_SUCCESS);
+
+	return error;
+}
+
+bool generate_asymmetric_encryption_key(psa_key_id_t *encryption_key_id)
+{
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+	psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
+
+	psa_set_key_id(&attributes, ENCRYPTION_KEY_ID);
+	psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
+	psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
+	psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
+	psa_set_key_bits(&attributes, 1024);
+
+	if (m_verbose)
+		printf("Generating RSA encryption key");
+
+	status = psa_generate_key(&attributes, encryption_key_id);
+	psa_reset_key_attributes(&attributes);
+
+	print_status(status);
+
+	return (status != PSA_SUCCESS);
+}
+
+bool encrypt_add_decrypt_message(const char *message, psa_key_id_t encryption_key_id)
+{
+	bool error = false;
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+	size_t message_len = strlen(message) + 1;
+
+	/* Encrypt a message */
+	if (m_verbose)
+		printf("Encrypt message: \"%s\" using RSA key: %d", message, encryption_key_id);
+
+	uint8_t ciphertext[256];
+	size_t ciphertext_len = 0;
+
+	status = psa_asymmetric_encrypt(encryption_key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
+					(const uint8_t *)message, message_len, NULL, 0, ciphertext,
+					sizeof(ciphertext), &ciphertext_len);
+	print_status(status);
+
+	if (m_verbose && (status == PSA_SUCCESS)) {
+		printf("\tEncrypted message: ");
+		print_byte_array(ciphertext, ciphertext_len);
+	}
+
+	error |= (status != PSA_SUCCESS);
+
+	/* Decrypt it */
+	if (m_verbose)
+		printf("Decrypting message using RSA key: %d", encryption_key_id);
+
+	uint8_t plaintext[256];
+	size_t plaintext_len = 0;
+
+	status = psa_asymmetric_decrypt(encryption_key_id, PSA_ALG_RSA_PKCS1V15_CRYPT, ciphertext,
+					ciphertext_len, NULL, 0, plaintext, sizeof(plaintext),
+					&plaintext_len);
+	print_status(status);
+
+	if (m_verbose && (status == PSA_SUCCESS)) {
+		if ((plaintext_len == message_len) &&
+		    (memcmp(message, plaintext, plaintext_len) == 0)) {
+			printf("\tDecrypted message: \"%s\"\n", plaintext);
+		} else {
+			printf("\tDecrypted message is different from original!: ");
+			print_byte_array(plaintext, plaintext_len);
+		}
+	}
+
+	error |= (status != PSA_SUCCESS);
+
+	return error;
+}
+
+bool export_public_key(psa_key_id_t signing_key_id)
+{
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+	uint8_t key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
+	size_t key_len = 0;
+
+	if (m_verbose)
+		printf("Exporting public key: %d", signing_key_id);
+
+	status = psa_export_public_key(signing_key_id, key_buf, sizeof(key_buf), &key_len);
+
+	print_status(status);
+
+	if (m_verbose && (status == PSA_SUCCESS)) {
+		printf("\tPublic key bytes: ");
+		print_byte_array(key_buf, key_len);
+	}
+
+	return (status != PSA_SUCCESS);
+}
+
+bool generate_random_number(size_t length)
+{
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+	uint8_t *buffer = (uint8_t *)malloc(length);
+
+	if (m_verbose)
+		printf("Generating random bytes length: %lu", length);
+
+	status = psa_generate_random(buffer, length);
+
+	print_status(status);
+
+	if (m_verbose && (status == PSA_SUCCESS)) {
+		printf("\tRandom bytes: ");
+		print_byte_array(buffer, length);
+	}
+
+	return (status != PSA_SUCCESS);
+}
+
+bool destroy_keys(psa_key_id_t signing_key_id, psa_key_id_t encryption_key_id)
+{
+	bool error = false;
+	psa_status_t status = PSA_ERROR_GENERIC_ERROR;
+
+	if (m_verbose)
+		printf("Destroying signing key: %d", signing_key_id);
+
+	status = psa_destroy_key(signing_key_id);
+	print_status(status);
+	error |= (status != PSA_SUCCESS);
+
+	if (m_verbose)
+		printf("Destroying encryption key: %d", encryption_key_id);
+
+	status = psa_destroy_key(encryption_key_id);
+	print_status(status);
+	error |= (status != PSA_SUCCESS);
+
+	return error;
+}
+
+bool run_ts_demo(bool is_verbose)
+{
+	psa_key_id_t signing_key_id = 0;
+	psa_key_id_t encryption_key_id = 0;
+	bool error = false;
+
+	m_verbose = is_verbose;
+	print_intro();
+	wait(1);
+	psa_crypto_init();
+	wait(1);
+	error |= generate_random_number(1);
+	wait(1);
+	error |= generate_random_number(7);
+	wait(1);
+	error |= generate_random_number(128);
+	wait(1);
+	error |= generate_signing_key(&signing_key_id);
+	wait(2);
+	error |= sign_and_verify_message("The quick brown fox", signing_key_id);
+	wait(3);
+	error |= sign_and_verify_message("jumps over the lazy dog", signing_key_id);
+	wait(3);
+	error |= generate_asymmetric_encryption_key(&encryption_key_id);
+	wait(2);
+	error |= encrypt_add_decrypt_message("Top secret", encryption_key_id);
+	wait(3);
+	error |= export_public_key(signing_key_id);
+	wait(2);
+	error |= destroy_keys(signing_key_id, encryption_key_id);
+	wait(2);
+
+	return error;
+}
diff --git a/components/app/ts-demo/ts-demo.cpp b/components/app/ts-demo/ts-demo.cpp
deleted file mode 100644
index 589f3b6..0000000
--- a/components/app/ts-demo/ts-demo.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <cstdio>
-#include <cstring>
-#include <unistd.h>
-#include <service/crypto/client/cpp/crypto_client.h>
-#include "ts-demo.h"
-
-class ts_demo {
-public:
-    ts_demo(crypto_client *crypto_client, bool is_verbose) :
-        m_crypto_client(crypto_client),
-        m_signing_key_id(0),
-        m_encryption_key_id(0),
-        m_verbose(is_verbose),
-        m_all_ok(true) {
-
-    }
-
-    ~ts_demo() {
-
-    }
-
-    bool is_all_ok() const {
-        return m_all_ok;
-    }
-
-    void print_intro() {
-
-        if (m_verbose) {
-            printf("\nDemonstrates use of trusted services from an application");
-            printf("\n---------------------------------------------------------");
-            printf("\nA client requests a set of crypto operations performed by");
-            printf("\nthe Crypto service.  Key storage for persistent keys is");
-            printf("\nprovided by the Secure Storage service via the ITS client.\n");
-            printf("\n");
-        }
-    }
-
-    void wait(int seconds) {
-
-        if (m_verbose) sleep(seconds);
-    }
-
-    void print_status(psa_status_t status) {
-
-            if (m_verbose) {
-
-            if (status == PSA_SUCCESS) {
-                printf("\n\tOperation successful\n");
-            }
-            else {
-                printf("\n\tOperation failed. op error: %d RPC call status %d\n",
-                    status, m_crypto_client->err_rpc_status());
-            }
-        }
-    }
-
-    void print_byte_array(const uint8_t *array, size_t len)
-    {
-        size_t count = 0;
-        size_t column = 0;
-
-        while (count < len) {
-
-            if (column == 0) printf("\n\t\t");
-            else printf(" ");
-
-            printf("%02X", array[count]);
-
-            ++count;
-            column = (column +1) % 8;
-        }
-
-        printf("\n");
-    }
-
-    void generate_signing_key()
-    {
-        psa_status_t status;
-        psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
-        psa_set_key_id(&attributes, SIGNING_KEY_ID);
-        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH);
-        psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256));
-        psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
-        psa_set_key_bits(&attributes, 256);
-
-        if (m_verbose) printf("Generating ECC signing key");
-
-        status = m_crypto_client->generate_key(&attributes, &m_signing_key_id);
-        psa_reset_key_attributes(&attributes);
-
-        print_status(status);
-
-        m_all_ok &= (status == PSA_SUCCESS);
-    }
-
-    void sign_and_verify_message(const char *message)
-    {
-
-        psa_status_t status;
-        uint8_t hash[100];
-        size_t hash_len = strlen(message) + 1;
-
-        if (hash_len > sizeof(hash)) hash_len = sizeof(hash) - 1;
-
-        memset(hash, 0, sizeof(hash));
-        memcpy(hash, message, hash_len);
-
-	    /* Sign message */
-        uint8_t signature[PSA_SIGNATURE_MAX_SIZE];
-        size_t signature_length;
-
-        if (m_verbose) printf("Signing message: \"%s\" using key: %d", hash, m_signing_key_id);
-
-        status = m_crypto_client->sign_hash(m_signing_key_id,
-            PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hash_len,
-            signature, sizeof(signature), &signature_length);
-
-        print_status(status);
-
-        if (m_verbose && (status == PSA_SUCCESS)) {
-            printf("\tSignature bytes: ");
-            print_byte_array(signature, signature_length);
-        }
-
-        m_all_ok &= (status == PSA_SUCCESS);
-
-        /* Verify signature against original message */
-        if (m_verbose) printf("Verify signature using original message: \"%s\"", hash);
-
-        status = m_crypto_client->verify_hash(m_signing_key_id,
-            PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hash_len,
-            signature, signature_length);
-
-        print_status(status);
-
-        m_all_ok &= (status == PSA_SUCCESS);
-
-        /* Verify signature against modified message */
-        hash[0] = '!';
-        if (m_verbose) printf("Verify signature using modified message: \"%s\"", hash);
-
-        status = m_crypto_client->verify_hash(m_signing_key_id,
-            PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), hash, hash_len,
-            signature, signature_length);
-
-        if (status == PSA_ERROR_INVALID_SIGNATURE) {
-            if (m_verbose) printf("\n\tSuccessfully detected modified message\n");
-        }
-        else {
-            print_status(status);
-        }
-
-        m_all_ok &= (status != PSA_SUCCESS);
-    }
-
-    void generate_asymmetric_encryption_key()
-    {
-        psa_status_t status;
-        psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
-
-        psa_set_key_id(&attributes, ENCRYPTION_KEY_ID);
-        psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
-        psa_set_key_algorithm(&attributes, PSA_ALG_RSA_PKCS1V15_CRYPT);
-        psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
-        psa_set_key_bits(&attributes, 1024);
-
-        if (m_verbose) printf("Generating RSA encryption key");
-
-        status = m_crypto_client->generate_key(&attributes, &m_encryption_key_id);
-        psa_reset_key_attributes(&attributes);
-
-        print_status(status);
-
-        m_all_ok &= (status == PSA_SUCCESS);
-    }
-
-    void encrypt_add_decrypt_message(const char *message)
-    {
-        psa_status_t status;
-        size_t message_len = strlen(message) + 1;
-
-        /* Encrypt a message */
-        if (m_verbose) printf("Encrypting message: \"%s\" using RSA key: %d", message, m_encryption_key_id);
-
-        uint8_t ciphertext[256];
-        size_t ciphertext_len = 0;
-
-        status = m_crypto_client->asymmetric_encrypt(m_encryption_key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
-                                (const uint8_t*)message, message_len, NULL, 0,
-                                ciphertext, sizeof(ciphertext), &ciphertext_len);
-        print_status(status);
-
-        if (m_verbose && (status == PSA_SUCCESS)) {
-            printf("\tEncrypted message: ");
-            print_byte_array(ciphertext, ciphertext_len);
-        }
-
-        m_all_ok &= (status == PSA_SUCCESS);
-
-        /* Decrypt it */
-        if (m_verbose) printf("Decrypting message using RSA key: %d", m_encryption_key_id);
-
-        uint8_t plaintext[256];
-        size_t plaintext_len = 0;
-
-        status = m_crypto_client->asymmetric_decrypt(m_encryption_key_id, PSA_ALG_RSA_PKCS1V15_CRYPT,
-                                ciphertext, ciphertext_len, NULL, 0,
-                                plaintext, sizeof(plaintext), &plaintext_len);
-        print_status(status);
-
-        if (m_verbose && (status == PSA_SUCCESS)) {
-
-            if ((plaintext_len == message_len) &&
-                (memcmp(message, plaintext, plaintext_len) == 0)) {
-                if (m_verbose) printf("\tDecrypted message: \"%s\"\n", plaintext);
-            }
-            else {
-                printf("\tDecrypted message is different from original!: ");
-                print_byte_array(plaintext, plaintext_len);
-            }
-        }
-
-        m_all_ok &= (status == PSA_SUCCESS);
-    }
-
-    void export_public_key()
-    {
-        psa_status_t status;
-        uint8_t key_buf[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
-        size_t key_len = 0;
-
-        if (m_verbose) printf("Exporting public key: %d", m_signing_key_id);
-
-        status = m_crypto_client->export_public_key(m_signing_key_id, key_buf, sizeof(key_buf), &key_len);
-
-        print_status(status);
-
-        if (m_verbose && (status == PSA_SUCCESS)) {
-            printf("\tPublic key bytes: ");
-            print_byte_array(key_buf, key_len);
-        }
-
-        m_all_ok &= (status == PSA_SUCCESS);
-    }
-
-    void generate_random_number(size_t length)
-    {
-        psa_status_t status;
-        uint8_t buffer[length];
-
-        if (m_verbose) printf("Generating random bytes length: %ld", length);
-
-        status = m_crypto_client->generate_random(buffer, length);
-
-        print_status(status);
-
-        if (m_verbose && (status == PSA_SUCCESS)) {
-            printf("\tRandom bytes: ");
-            print_byte_array(buffer, length);
-        }
-
-        m_all_ok &= (status == PSA_SUCCESS);
-    }
-
-    void destroy_keys()
-    {
-        psa_status_t status;
-
-        if (m_verbose) printf("Destroying signing key: %d", m_signing_key_id);
-        status = m_crypto_client->destroy_key(m_signing_key_id);
-        print_status(status);
-        m_all_ok &= (status == PSA_SUCCESS);
-
-        if (m_verbose) printf("Destroying encryption key: %d", m_encryption_key_id);
-        status = m_crypto_client->destroy_key(m_encryption_key_id);
-        print_status(status);
-        m_all_ok &= (status == PSA_SUCCESS);
-    }
-
-private:
-
-    static const psa_key_id_t SIGNING_KEY_ID = 0x100;
-    static const psa_key_id_t ENCRYPTION_KEY_ID = 0x101;
-
-    crypto_client *m_crypto_client;
-    psa_key_id_t m_signing_key_id;
-    psa_key_id_t m_encryption_key_id;
-
-    bool m_verbose;
-    bool m_all_ok;
-};
-
-
-int run_ts_demo(crypto_client *crypto_client, bool is_verbose) {
-
-    ts_demo demo(crypto_client, is_verbose);
-
-    demo.print_intro();
-    demo.wait(1);
-    demo.generate_random_number(1);
-    demo.wait(1);
-    demo.generate_random_number(7);
-    demo.wait(1);
-    demo.generate_random_number(128);
-    demo.wait(1);
-    demo.generate_signing_key();
-    demo.wait(2);
-    demo.sign_and_verify_message("The quick brown fox");
-    demo.wait(3);
-    demo.sign_and_verify_message("jumps over the lazy dog");
-    demo.wait(3);
-    demo.generate_asymmetric_encryption_key();
-    demo.wait(2);
-    demo.encrypt_add_decrypt_message("Top secret");
-    demo.wait(3);
-    demo.export_public_key();
-    demo.wait(2);
-    demo.destroy_keys();
-    demo.wait(2);
-
-    return demo.is_all_ok() ? 0 : -1;
-}
diff --git a/components/app/ts-demo/ts-demo.h b/components/app/ts-demo/ts-demo.h
index 96de474..34fbbbf 100644
--- a/components/app/ts-demo/ts-demo.h
+++ b/components/app/ts-demo/ts-demo.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,8 +7,16 @@
 #ifndef TS_DEMO_H
 #define TS_DEMO_H
 
-#include <service/crypto/client/cpp/crypto_client.h>
+#include <stdbool.h>
 
-int run_ts_demo(crypto_client *crypto_client, bool is_verbose);
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool run_ts_demo(bool is_verbose);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* TS_DEMO_H */
diff --git a/components/common/dlmalloc/component.cmake b/components/common/dlmalloc/component.cmake
new file mode 100644
index 0000000..909279c
--- /dev/null
+++ b/components/common/dlmalloc/component.cmake
@@ -0,0 +1,15 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#-------------------------------------------------------------------------------
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/malloc_wrapper.c"
+)
+
+# TODO: remove workaround
+set_source_files_properties(
+	"${CMAKE_CURRENT_LIST_DIR}/malloc_wrapper.c" PROPERTIES COMPILE_FLAGS
+	"-fno-builtin"
+)
diff --git a/components/common/dlmalloc/malloc.c b/components/common/dlmalloc/malloc.c
new file mode 100644
index 0000000..35003d1
--- /dev/null
+++ b/components/common/dlmalloc/malloc.c
@@ -0,0 +1,6291 @@
+/*
+Copyright 2023 Doug Lea
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+* Version 2.8.6 Wed Aug 29 06:57:58 2012  Doug Lea
+  Re-licensed 25 Sep 2023 with MIT-0 replacing obsolete CC0
+  See https://opensource.org/license/mit-0/
+
+* Quickstart
+
+  This library is all in one file to simplify the most common usage:
+  ftp it, compile it (-O3), and link it into another program. All of
+  the compile-time options default to reasonable values for use on
+  most platforms.  You might later want to step through various
+  compile-time and dynamic tuning options.
+
+  For convenience, an include file for code using this malloc is at:
+     ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.6.h
+  You don't really need this .h file unless you call functions not
+  defined in your system include files.  The .h file contains only the
+  excerpts from this file needed for using this malloc on ANSI C/C++
+  systems, so long as you haven't changed compile-time options about
+  naming and tuning parameters.  If you do, then you can create your
+  own malloc.h that does include all settings by cutting at the point
+  indicated below. Note that you may already by default be using a C
+  library containing a malloc that is based on some version of this
+  malloc (for example in linux). You might still want to use the one
+  in this file to customize settings or to avoid overheads associated
+  with library versions.
+
+* Vital statistics:
+
+  Supported pointer/size_t representation:       4 or 8 bytes
+       size_t MUST be an unsigned type of the same width as
+       pointers. (If you are using an ancient system that declares
+       size_t as a signed type, or need it to be a different width
+       than pointers, you can use a previous release of this malloc
+       (e.g. 2.7.2) supporting these.)
+
+  Alignment:                                     8 bytes (minimum)
+       This suffices for nearly all current machines and C compilers.
+       However, you can define MALLOC_ALIGNMENT to be wider than this
+       if necessary (up to 128bytes), at the expense of using more space.
+
+  Minimum overhead per allocated chunk:   4 or  8 bytes (if 4byte sizes)
+                                          8 or 16 bytes (if 8byte sizes)
+       Each malloced chunk has a hidden word of overhead holding size
+       and status information, and additional cross-check word
+       if FOOTERS is defined.
+
+  Minimum allocated size: 4-byte ptrs:  16 bytes    (including overhead)
+                          8-byte ptrs:  32 bytes    (including overhead)
+
+       Even a request for zero bytes (i.e., malloc(0)) returns a
+       pointer to something of the minimum allocatable size.
+       The maximum overhead wastage (i.e., number of extra bytes
+       allocated than were requested in malloc) is less than or equal
+       to the minimum size, except for requests >= mmap_threshold that
+       are serviced via mmap(), where the worst case wastage is about
+       32 bytes plus the remainder from a system page (the minimal
+       mmap unit); typically 4096 or 8192 bytes.
+
+  Security: static-safe; optionally more or less
+       The "security" of malloc refers to the ability of malicious
+       code to accentuate the effects of errors (for example, freeing
+       space that is not currently malloc'ed or overwriting past the
+       ends of chunks) in code that calls malloc.  This malloc
+       guarantees not to modify any memory locations below the base of
+       heap, i.e., static variables, even in the presence of usage
+       errors.  The routines additionally detect most improper frees
+       and reallocs.  All this holds as long as the static bookkeeping
+       for malloc itself is not corrupted by some other means.  This
+       is only one aspect of security -- these checks do not, and
+       cannot, detect all possible programming errors.
+
+       If FOOTERS is defined nonzero, then each allocated chunk
+       carries an additional check word to verify that it was malloced
+       from its space.  These check words are the same within each
+       execution of a program using malloc, but differ across
+       executions, so externally crafted fake chunks cannot be
+       freed. This improves security by rejecting frees/reallocs that
+       could corrupt heap memory, in addition to the checks preventing
+       writes to statics that are always on.  This may further improve
+       security at the expense of time and space overhead.  (Note that
+       FOOTERS may also be worth using with MSPACES.)
+
+       By default detected errors cause the program to abort (calling
+       "abort()"). You can override this to instead proceed past
+       errors by defining PROCEED_ON_ERROR.  In this case, a bad free
+       has no effect, and a malloc that encounters a bad address
+       caused by user overwrites will ignore the bad address by
+       dropping pointers and indices to all known memory. This may
+       be appropriate for programs that should continue if at all
+       possible in the face of programming errors, although they may
+       run out of memory because dropped memory is never reclaimed.
+
+       If you don't like either of these options, you can define
+       CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything
+       else. And if if you are sure that your program using malloc has
+       no errors or vulnerabilities, you can define INSECURE to 1,
+       which might (or might not) provide a small performance improvement.
+
+       It is also possible to limit the maximum total allocatable
+       space, using malloc_set_footprint_limit. This is not
+       designed as a security feature in itself (calls to set limits
+       are not screened or privileged), but may be useful as one
+       aspect of a secure implementation.
+
+  Thread-safety: NOT thread-safe unless USE_LOCKS defined non-zero
+       When USE_LOCKS is defined, each public call to malloc, free,
+       etc is surrounded with a lock. By default, this uses a plain
+       pthread mutex, win32 critical section, or a spin-lock if if
+       available for the platform and not disabled by setting
+       USE_SPIN_LOCKS=0.  However, if USE_RECURSIVE_LOCKS is defined,
+       recursive versions are used instead (which are not required for
+       base functionality but may be needed in layered extensions).
+       Using a global lock is not especially fast, and can be a major
+       bottleneck.  It is designed only to provide minimal protection
+       in concurrent environments, and to provide a basis for
+       extensions.  If you are using malloc in a concurrent program,
+       consider instead using nedmalloc
+       (http://www.nedprod.com/programs/portable/nedmalloc/) or
+       ptmalloc (See http://www.malloc.de), which are derived from
+       versions of this malloc.
+
+  System requirements: Any combination of MORECORE and/or MMAP/MUNMAP
+       This malloc can use unix sbrk or any emulation (invoked using
+       the CALL_MORECORE macro) and/or mmap/munmap or any emulation
+       (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system
+       memory.  On most unix systems, it tends to work best if both
+       MORECORE and MMAP are enabled.  On Win32, it uses emulations
+       based on VirtualAlloc. It also uses common C library functions
+       like memset.
+
+  Compliance: I believe it is compliant with the Single Unix Specification
+       (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably
+       others as well.
+
+* Overview of algorithms
+
+  This is not the fastest, most space-conserving, most portable, or
+  most tunable malloc ever written. However it is among the fastest
+  while also being among the most space-conserving, portable and
+  tunable.  Consistent balance across these factors results in a good
+  general-purpose allocator for malloc-intensive programs.
+
+  In most ways, this malloc is a best-fit allocator. Generally, it
+  chooses the best-fitting existing chunk for a request, with ties
+  broken in approximately least-recently-used order. (This strategy
+  normally maintains low fragmentation.) However, for requests less
+  than 256bytes, it deviates from best-fit when there is not an
+  exactly fitting available chunk by preferring to use space adjacent
+  to that used for the previous small request, as well as by breaking
+  ties in approximately most-recently-used order. (These enhance
+  locality of series of small allocations.)  And for very large requests
+  (>= 256Kb by default), it relies on system memory mapping
+  facilities, if supported.  (This helps avoid carrying around and
+  possibly fragmenting memory used only for large chunks.)
+
+  All operations (except malloc_stats and mallinfo) have execution
+  times that are bounded by a constant factor of the number of bits in
+  a size_t, not counting any clearing in calloc or copying in realloc,
+  or actions surrounding MORECORE and MMAP that have times
+  proportional to the number of non-contiguous regions returned by
+  system allocation routines, which is often just 1. In real-time
+  applications, you can optionally suppress segment traversals using
+  NO_SEGMENT_TRAVERSAL, which assures bounded execution even when
+  system allocators return non-contiguous spaces, at the typical
+  expense of carrying around more memory and increased fragmentation.
+
+  The implementation is not very modular and seriously overuses
+  macros. Perhaps someday all C compilers will do as good a job
+  inlining modular code as can now be done by brute-force expansion,
+  but now, enough of them seem not to.
+
+  Some compilers issue a lot of warnings about code that is
+  dead/unreachable only on some platforms, and also about intentional
+  uses of negation on unsigned types. All known cases of each can be
+  ignored.
+
+  For a longer but out of date high-level description, see
+     http://gee.cs.oswego.edu/dl/html/malloc.html
+
+* MSPACES
+  If MSPACES is defined, then in addition to malloc, free, etc.,
+  this file also defines mspace_malloc, mspace_free, etc. These
+  are versions of malloc routines that take an "mspace" argument
+  obtained using create_mspace, to control all internal bookkeeping.
+  If ONLY_MSPACES is defined, only these versions are compiled.
+  So if you would like to use this allocator for only some allocations,
+  and your system malloc for others, you can compile with
+  ONLY_MSPACES and then do something like...
+    static mspace mymspace = create_mspace(0,0); // for example
+    #define mymalloc(bytes)  mspace_malloc(mymspace, bytes)
+
+  (Note: If you only need one instance of an mspace, you can instead
+  use "USE_DL_PREFIX" to relabel the global malloc.)
+
+  You can similarly create thread-local allocators by storing
+  mspaces as thread-locals. For example:
+    static __thread mspace tlms = 0;
+    void*  tlmalloc(size_t bytes) {
+      if (tlms == 0) tlms = create_mspace(0, 0);
+      return mspace_malloc(tlms, bytes);
+    }
+    void  tlfree(void* mem) { mspace_free(tlms, mem); }
+
+  Unless FOOTERS is defined, each mspace is completely independent.
+  You cannot allocate from one and free to another (although
+  conformance is only weakly checked, so usage errors are not always
+  caught). If FOOTERS is defined, then each chunk carries around a tag
+  indicating its originating mspace, and frees are directed to their
+  originating spaces. Normally, this requires use of locks.
+
+ -------------------------  Compile-time options ---------------------------
+
+Be careful in setting #define values for numerical constants of type
+size_t. On some systems, literal values are not automatically extended
+to size_t precision unless they are explicitly casted. You can also
+use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below.
+
+WIN32                    default: defined if _WIN32 defined
+  Defining WIN32 sets up defaults for MS environment and compilers.
+  Otherwise defaults are for unix. Beware that there seem to be some
+  cases where this malloc might not be a pure drop-in replacement for
+  Win32 malloc: Random-looking failures from Win32 GDI API's (eg;
+  SetDIBits()) may be due to bugs in some video driver implementations
+  when pixel buffers are malloc()ed, and the region spans more than
+  one VirtualAlloc()ed region. Because dlmalloc uses a small (64Kb)
+  default granularity, pixel buffers may straddle virtual allocation
+  regions more often than when using the Microsoft allocator.  You can
+  avoid this by using VirtualAlloc() and VirtualFree() for all pixel
+  buffers rather than using malloc().  If this is not possible,
+  recompile this malloc with a larger DEFAULT_GRANULARITY. Note:
+  in cases where MSC and gcc (cygwin) are known to differ on WIN32,
+  conditions use _MSC_VER to distinguish them.
+
+DLMALLOC_EXPORT       default: extern
+  Defines how public APIs are declared. If you want to export via a
+  Windows DLL, you might define this as
+    #define DLMALLOC_EXPORT extern  __declspec(dllexport)
+  If you want a POSIX ELF shared object, you might use
+    #define DLMALLOC_EXPORT extern __attribute__((visibility("default")))
+
+MALLOC_ALIGNMENT         default: (size_t)(2 * sizeof(void *))
+  Controls the minimum alignment for malloc'ed chunks.  It must be a
+  power of two and at least 8, even on machines for which smaller
+  alignments would suffice. It may be defined as larger than this
+  though. Note however that code and data structures are optimized for
+  the case of 8-byte alignment.
+
+MSPACES                  default: 0 (false)
+  If true, compile in support for independent allocation spaces.
+  This is only supported if HAVE_MMAP is true.
+
+ONLY_MSPACES             default: 0 (false)
+  If true, only compile in mspace versions, not regular versions.
+
+USE_LOCKS                default: 0 (false)
+  Causes each call to each public routine to be surrounded with
+  pthread or WIN32 mutex lock/unlock. (If set true, this can be
+  overridden on a per-mspace basis for mspace versions.) If set to a
+  non-zero value other than 1, locks are used, but their
+  implementation is left out, so lock functions must be supplied manually,
+  as described below.
+
+USE_SPIN_LOCKS           default: 1 iff USE_LOCKS and spin locks available
+  If true, uses custom spin locks for locking. This is currently
+  supported only gcc >= 4.1, older gccs on x86 platforms, and recent
+  MS compilers.  Otherwise, posix locks or win32 critical sections are
+  used.
+
+USE_RECURSIVE_LOCKS      default: not defined
+  If defined nonzero, uses recursive (aka reentrant) locks, otherwise
+  uses plain mutexes. This is not required for malloc proper, but may
+  be needed for layered allocators such as nedmalloc.
+
+LOCK_AT_FORK            default: not defined
+  If defined nonzero, performs pthread_atfork upon initialization
+  to initialize child lock while holding parent lock. The implementation
+  assumes that pthread locks (not custom locks) are being used. In other
+  cases, you may need to customize the implementation.
+
+FOOTERS                  default: 0
+  If true, provide extra checking and dispatching by placing
+  information in the footers of allocated chunks. This adds
+  space and time overhead.
+
+INSECURE                 default: 0
+  If true, omit checks for usage errors and heap space overwrites.
+
+USE_DL_PREFIX            default: NOT defined
+  Causes compiler to prefix all public routines with the string 'dl'.
+  This can be useful when you only want to use this malloc in one part
+  of a program, using your regular system malloc elsewhere.
+
+MALLOC_INSPECT_ALL       default: NOT defined
+  If defined, compiles malloc_inspect_all and mspace_inspect_all, that
+  perform traversal of all heap space.  Unless access to these
+  functions is otherwise restricted, you probably do not want to
+  include them in secure implementations.
+
+ABORT                    default: defined as abort()
+  Defines how to abort on failed checks.  On most systems, a failed
+  check cannot die with an "assert" or even print an informative
+  message, because the underlying print routines in turn call malloc,
+  which will fail again.  Generally, the best policy is to simply call
+  abort(). It's not very useful to do more than this because many
+  errors due to overwriting will show up as address faults (null, odd
+  addresses etc) rather than malloc-triggered checks, so will also
+  abort.  Also, most compilers know that abort() does not return, so
+  can better optimize code conditionally calling it.
+
+PROCEED_ON_ERROR           default: defined as 0 (false)
+  Controls whether detected bad addresses cause them to bypassed
+  rather than aborting. If set, detected bad arguments to free and
+  realloc are ignored. And all bookkeeping information is zeroed out
+  upon a detected overwrite of freed heap space, thus losing the
+  ability to ever return it from malloc again, but enabling the
+  application to proceed. If PROCEED_ON_ERROR is defined, the
+  static variable malloc_corruption_error_count is compiled in
+  and can be examined to see if errors have occurred. This option
+  generates slower code than the default abort policy.
+
+DEBUG                    default: NOT defined
+  The DEBUG setting is mainly intended for people trying to modify
+  this code or diagnose problems when porting to new platforms.
+  However, it may also be able to better isolate user errors than just
+  using runtime checks.  The assertions in the check routines spell
+  out in more detail the assumptions and invariants underlying the
+  algorithms.  The checking is fairly extensive, and will slow down
+  execution noticeably. Calling malloc_stats or mallinfo with DEBUG
+  set will attempt to check every non-mmapped allocated and free chunk
+  in the course of computing the summaries.
+
+ABORT_ON_ASSERT_FAILURE   default: defined as 1 (true)
+  Debugging assertion failures can be nearly impossible if your
+  version of the assert macro causes malloc to be called, which will
+  lead to a cascade of further failures, blowing the runtime stack.
+  ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(),
+  which will usually make debugging easier.
+
+MALLOC_FAILURE_ACTION     default: sets errno to ENOMEM, or no-op on win32
+  The action to take before "return 0" when malloc fails to be able to
+  return memory because there is none available.
+
+HAVE_MORECORE             default: 1 (true) unless win32 or ONLY_MSPACES
+  True if this system supports sbrk or an emulation of it.
+
+MORECORE                  default: sbrk
+  The name of the sbrk-style system routine to call to obtain more
+  memory.  See below for guidance on writing custom MORECORE
+  functions. The type of the argument to sbrk/MORECORE varies across
+  systems.  It cannot be size_t, because it supports negative
+  arguments, so it is normally the signed type of the same width as
+  size_t (sometimes declared as "intptr_t").  It doesn't much matter
+  though. Internally, we only call it with arguments less than half
+  the max value of a size_t, which should work across all reasonable
+  possibilities, although sometimes generating compiler warnings.
+
+MORECORE_CONTIGUOUS       default: 1 (true) if HAVE_MORECORE
+  If true, take advantage of fact that consecutive calls to MORECORE
+  with positive arguments always return contiguous increasing
+  addresses.  This is true of unix sbrk. It does not hurt too much to
+  set it true anyway, since malloc copes with non-contiguities.
+  Setting it false when definitely non-contiguous saves time
+  and possibly wasted space it would take to discover this though.
+
+MORECORE_CANNOT_TRIM      default: NOT defined
+  True if MORECORE cannot release space back to the system when given
+  negative arguments. This is generally necessary only if you are
+  using a hand-crafted MORECORE function that cannot handle negative
+  arguments.
+
+NO_SEGMENT_TRAVERSAL       default: 0
+  If non-zero, suppresses traversals of memory segments
+  returned by either MORECORE or CALL_MMAP. This disables
+  merging of segments that are contiguous, and selectively
+  releasing them to the OS if unused, but bounds execution times.
+
+HAVE_MMAP                 default: 1 (true)
+  True if this system supports mmap or an emulation of it.  If so, and
+  HAVE_MORECORE is not true, MMAP is used for all system
+  allocation. If set and HAVE_MORECORE is true as well, MMAP is
+  primarily used to directly allocate very large blocks. It is also
+  used as a backup strategy in cases where MORECORE fails to provide
+  space from system. Note: A single call to MUNMAP is assumed to be
+  able to unmap memory that may have be allocated using multiple calls
+  to MMAP, so long as they are adjacent.
+
+HAVE_MREMAP               default: 1 on linux, else 0
+  If true realloc() uses mremap() to re-allocate large blocks and
+  extend or shrink allocation spaces.
+
+MMAP_CLEARS               default: 1 except on WINCE.
+  True if mmap clears memory so calloc doesn't need to. This is true
+  for standard unix mmap using /dev/zero and on WIN32 except for WINCE.
+
+USE_BUILTIN_FFS            default: 0 (i.e., not used)
+  Causes malloc to use the builtin ffs() function to compute indices.
+  Some compilers may recognize and intrinsify ffs to be faster than the
+  supplied C version. Also, the case of x86 using gcc is special-cased
+  to an asm instruction, so is already as fast as it can be, and so
+  this setting has no effect. Similarly for Win32 under recent MS compilers.
+  (On most x86s, the asm version is only slightly faster than the C version.)
+
+malloc_getpagesize         default: derive from system includes, or 4096.
+  The system page size. To the extent possible, this malloc manages
+  memory from the system in page-size units.  This may be (and
+  usually is) a function rather than a constant. This is ignored
+  if WIN32, where page size is determined using getSystemInfo during
+  initialization.
+
+USE_DEV_RANDOM             default: 0 (i.e., not used)
+  Causes malloc to use /dev/random to initialize secure magic seed for
+  stamping footers. Otherwise, the current time is used.
+
+NO_MALLINFO                default: 0
+  If defined, don't compile "mallinfo". This can be a simple way
+  of dealing with mismatches between system declarations and
+  those in this file.
+
+MALLINFO_FIELD_TYPE        default: size_t
+  The type of the fields in the mallinfo struct. This was originally
+  defined as "int" in SVID etc, but is more usefully defined as
+  size_t. The value is used only if  HAVE_USR_INCLUDE_MALLOC_H is not set
+
+NO_MALLOC_STATS            default: 0
+  If defined, don't compile "malloc_stats". This avoids calls to
+  fprintf and bringing in stdio dependencies you might not want.
+
+REALLOC_ZERO_BYTES_FREES    default: not defined
+  This should be set if a call to realloc with zero bytes should
+  be the same as a call to free. Some people think it should. Otherwise,
+  since this malloc returns a unique pointer for malloc(0), so does
+  realloc(p, 0).
+
+LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H
+LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H,  LACKS_ERRNO_H
+LACKS_STDLIB_H LACKS_SCHED_H LACKS_TIME_H  default: NOT defined unless on WIN32
+  Define these if your system does not have these header files.
+  You might need to manually insert some of the declarations they provide.
+
+DEFAULT_GRANULARITY        default: page size if MORECORE_CONTIGUOUS,
+                                system_info.dwAllocationGranularity in WIN32,
+                                otherwise 64K.
+      Also settable using mallopt(M_GRANULARITY, x)
+  The unit for allocating and deallocating memory from the system.  On
+  most systems with contiguous MORECORE, there is no reason to
+  make this more than a page. However, systems with MMAP tend to
+  either require or encourage larger granularities.  You can increase
+  this value to prevent system allocation functions to be called so
+  often, especially if they are slow.  The value must be at least one
+  page and must be a power of two.  Setting to 0 causes initialization
+  to either page size or win32 region size.  (Note: In previous
+  versions of malloc, the equivalent of this option was called
+  "TOP_PAD")
+
+DEFAULT_TRIM_THRESHOLD    default: 2MB
+      Also settable using mallopt(M_TRIM_THRESHOLD, x)
+  The maximum amount of unused top-most memory to keep before
+  releasing via malloc_trim in free().  Automatic trimming is mainly
+  useful in long-lived programs using contiguous MORECORE.  Because
+  trimming via sbrk can be slow on some systems, and can sometimes be
+  wasteful (in cases where programs immediately afterward allocate
+  more large chunks) the value should be high enough so that your
+  overall system performance would improve by releasing this much
+  memory.  As a rough guide, you might set to a value close to the
+  average size of a process (program) running on your system.
+  Releasing this much memory would allow such a process to run in
+  memory.  Generally, it is worth tuning trim thresholds when a
+  program undergoes phases where several large chunks are allocated
+  and released in ways that can reuse each other's storage, perhaps
+  mixed with phases where there are no such chunks at all. The trim
+  value must be greater than page size to have any useful effect.  To
+  disable trimming completely, you can set to MAX_SIZE_T. Note that the trick
+  some people use of mallocing a huge space and then freeing it at
+  program startup, in an attempt to reserve system memory, doesn't
+  have the intended effect under automatic trimming, since that memory
+  will immediately be returned to the system.
+
+DEFAULT_MMAP_THRESHOLD       default: 256K
+      Also settable using mallopt(M_MMAP_THRESHOLD, x)
+  The request size threshold for using MMAP to directly service a
+  request. Requests of at least this size that cannot be allocated
+  using already-existing space will be serviced via mmap.  (If enough
+  normal freed space already exists it is used instead.)  Using mmap
+  segregates relatively large chunks of memory so that they can be
+  individually obtained and released from the host system. A request
+  serviced through mmap is never reused by any other request (at least
+  not directly; the system may just so happen to remap successive
+  requests to the same locations).  Segregating space in this way has
+  the benefits that: Mmapped space can always be individually released
+  back to the system, which helps keep the system level memory demands
+  of a long-lived program low.  Also, mapped memory doesn't become
+  `locked' between other chunks, as can happen with normally allocated
+  chunks, which means that even trimming via malloc_trim would not
+  release them.  However, it has the disadvantage that the space
+  cannot be reclaimed, consolidated, and then used to service later
+  requests, as happens with normal chunks.  The advantages of mmap
+  nearly always outweigh disadvantages for "large" chunks, but the
+  value of "large" may vary across systems.  The default is an
+  empirically derived value that works well in most systems. You can
+  disable mmap by setting to MAX_SIZE_T.
+
+MAX_RELEASE_CHECK_RATE   default: 4095 unless not HAVE_MMAP
+  The number of consolidated frees between checks to release
+  unused segments when freeing. When using non-contiguous segments,
+  especially with multiple mspaces, checking only for topmost space
+  doesn't always suffice to trigger trimming. To compensate for this,
+  free() will, with a period of MAX_RELEASE_CHECK_RATE (or the
+  current number of segments, if greater) try to release unused
+  segments to the OS when freeing chunks that result in
+  consolidation. The best value for this parameter is a compromise
+  between slowing down frees with relatively costly checks that
+  rarely trigger versus holding on to unused memory. To effectively
+  disable, set to MAX_SIZE_T. This may lead to a very slight speed
+  improvement at the expense of carrying around more memory.
+*/
+
+/* Version identifier to allow people to support multiple versions */
+#ifndef DLMALLOC_VERSION
+#define DLMALLOC_VERSION 20806
+#endif /* DLMALLOC_VERSION */
+
+#ifndef DLMALLOC_EXPORT
+#define DLMALLOC_EXPORT extern
+#endif
+
+#ifndef WIN32
+#ifdef _WIN32
+#define WIN32 1
+#endif  /* _WIN32 */
+#ifdef _WIN32_WCE
+#define LACKS_FCNTL_H
+#define WIN32 1
+#endif /* _WIN32_WCE */
+#endif  /* WIN32 */
+#ifdef WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <tchar.h>
+#define HAVE_MMAP 1
+#define HAVE_MORECORE 0
+#define LACKS_UNISTD_H
+#define LACKS_SYS_PARAM_H
+#define LACKS_SYS_MMAN_H
+#define LACKS_STRING_H
+#define LACKS_STRINGS_H
+#define LACKS_SYS_TYPES_H
+#define LACKS_ERRNO_H
+#define LACKS_SCHED_H
+#ifndef MALLOC_FAILURE_ACTION
+#define MALLOC_FAILURE_ACTION
+#endif /* MALLOC_FAILURE_ACTION */
+#ifndef MMAP_CLEARS
+#ifdef _WIN32_WCE /* WINCE reportedly does not clear */
+#define MMAP_CLEARS 0
+#else
+#define MMAP_CLEARS 1
+#endif /* _WIN32_WCE */
+#endif /*MMAP_CLEARS */
+#endif  /* WIN32 */
+
+#if defined(DARWIN) || defined(_DARWIN)
+/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */
+#ifndef HAVE_MORECORE
+#define HAVE_MORECORE 0
+#define HAVE_MMAP 1
+/* OSX allocators provide 16 byte alignment */
+#ifndef MALLOC_ALIGNMENT
+#define MALLOC_ALIGNMENT ((size_t)16U)
+#endif
+#endif  /* HAVE_MORECORE */
+#endif  /* DARWIN */
+
+#ifndef LACKS_SYS_TYPES_H
+#include <sys/types.h>  /* For size_t */
+#endif  /* LACKS_SYS_TYPES_H */
+
+/* The maximum possible size_t value has all bits set */
+#define MAX_SIZE_T           (~(size_t)0)
+
+#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */
+#define USE_LOCKS  ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \
+                    (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0))
+#endif /* USE_LOCKS */
+
+#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */
+#if ((defined(__GNUC__) &&                                              \
+      ((__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) ||      \
+       defined(__i386__) || defined(__x86_64__))) ||                    \
+     (defined(_MSC_VER) && _MSC_VER>=1310))
+#ifndef USE_SPIN_LOCKS
+#define USE_SPIN_LOCKS 1
+#endif /* USE_SPIN_LOCKS */
+#elif USE_SPIN_LOCKS
+#error "USE_SPIN_LOCKS defined without implementation"
+#endif /* ... locks available... */
+#elif !defined(USE_SPIN_LOCKS)
+#define USE_SPIN_LOCKS 0
+#endif /* USE_LOCKS */
+
+#ifndef ONLY_MSPACES
+#define ONLY_MSPACES 0
+#endif  /* ONLY_MSPACES */
+#ifndef MSPACES
+#if ONLY_MSPACES
+#define MSPACES 1
+#else   /* ONLY_MSPACES */
+#define MSPACES 0
+#endif  /* ONLY_MSPACES */
+#endif  /* MSPACES */
+#ifndef MALLOC_ALIGNMENT
+#define MALLOC_ALIGNMENT ((size_t)(2 * sizeof(void *)))
+#endif  /* MALLOC_ALIGNMENT */
+#ifndef FOOTERS
+#define FOOTERS 0
+#endif  /* FOOTERS */
+#ifndef ABORT
+#define ABORT  abort()
+#endif  /* ABORT */
+#ifndef ABORT_ON_ASSERT_FAILURE
+#define ABORT_ON_ASSERT_FAILURE 1
+#endif  /* ABORT_ON_ASSERT_FAILURE */
+#ifndef PROCEED_ON_ERROR
+#define PROCEED_ON_ERROR 0
+#endif  /* PROCEED_ON_ERROR */
+
+#ifndef INSECURE
+#define INSECURE 0
+#endif  /* INSECURE */
+#ifndef MALLOC_INSPECT_ALL
+#define MALLOC_INSPECT_ALL 0
+#endif  /* MALLOC_INSPECT_ALL */
+#ifndef HAVE_MMAP
+#define HAVE_MMAP 1
+#endif  /* HAVE_MMAP */
+#ifndef MMAP_CLEARS
+#define MMAP_CLEARS 1
+#endif  /* MMAP_CLEARS */
+#ifndef HAVE_MREMAP
+#ifdef linux
+#define HAVE_MREMAP 1
+#define _GNU_SOURCE /* Turns on mremap() definition */
+#else   /* linux */
+#define HAVE_MREMAP 0
+#endif  /* linux */
+#endif  /* HAVE_MREMAP */
+#ifndef MALLOC_FAILURE_ACTION
+#define MALLOC_FAILURE_ACTION  errno = ENOMEM;
+#endif  /* MALLOC_FAILURE_ACTION */
+#ifndef HAVE_MORECORE
+#if ONLY_MSPACES
+#define HAVE_MORECORE 0
+#else   /* ONLY_MSPACES */
+#define HAVE_MORECORE 1
+#endif  /* ONLY_MSPACES */
+#endif  /* HAVE_MORECORE */
+#if !HAVE_MORECORE
+#define MORECORE_CONTIGUOUS 0
+#else   /* !HAVE_MORECORE */
+#define MORECORE_DEFAULT sbrk
+#ifndef MORECORE_CONTIGUOUS
+#define MORECORE_CONTIGUOUS 1
+#endif  /* MORECORE_CONTIGUOUS */
+#endif  /* HAVE_MORECORE */
+#ifndef DEFAULT_GRANULARITY
+#if (MORECORE_CONTIGUOUS || defined(WIN32))
+#define DEFAULT_GRANULARITY (0)  /* 0 means to compute in init_mparams */
+#else   /* MORECORE_CONTIGUOUS */
+#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U)
+#endif  /* MORECORE_CONTIGUOUS */
+#endif  /* DEFAULT_GRANULARITY */
+#ifndef DEFAULT_TRIM_THRESHOLD
+#ifndef MORECORE_CANNOT_TRIM
+#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U)
+#else   /* MORECORE_CANNOT_TRIM */
+#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
+#endif  /* MORECORE_CANNOT_TRIM */
+#endif  /* DEFAULT_TRIM_THRESHOLD */
+#ifndef DEFAULT_MMAP_THRESHOLD
+#if HAVE_MMAP
+#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U)
+#else   /* HAVE_MMAP */
+#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T
+#endif  /* HAVE_MMAP */
+#endif  /* DEFAULT_MMAP_THRESHOLD */
+#ifndef MAX_RELEASE_CHECK_RATE
+#if HAVE_MMAP
+#define MAX_RELEASE_CHECK_RATE 4095
+#else
+#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T
+#endif /* HAVE_MMAP */
+#endif /* MAX_RELEASE_CHECK_RATE */
+#ifndef USE_BUILTIN_FFS
+#define USE_BUILTIN_FFS 0
+#endif  /* USE_BUILTIN_FFS */
+#ifndef USE_DEV_RANDOM
+#define USE_DEV_RANDOM 0
+#endif  /* USE_DEV_RANDOM */
+#ifndef NO_MALLINFO
+#define NO_MALLINFO 0
+#endif  /* NO_MALLINFO */
+#ifndef MALLINFO_FIELD_TYPE
+#define MALLINFO_FIELD_TYPE size_t
+#endif  /* MALLINFO_FIELD_TYPE */
+#ifndef NO_MALLOC_STATS
+#define NO_MALLOC_STATS 0
+#endif  /* NO_MALLOC_STATS */
+#ifndef NO_SEGMENT_TRAVERSAL
+#define NO_SEGMENT_TRAVERSAL 0
+#endif /* NO_SEGMENT_TRAVERSAL */
+
+/*
+  mallopt tuning options.  SVID/XPG defines four standard parameter
+  numbers for mallopt, normally defined in malloc.h.  None of these
+  are used in this malloc, so setting them has no effect. But this
+  malloc does support the following options.
+*/
+
+#define M_TRIM_THRESHOLD     (-1)
+#define M_GRANULARITY        (-2)
+#define M_MMAP_THRESHOLD     (-3)
+
+/* ------------------------ Mallinfo declarations ------------------------ */
+
+#if !NO_MALLINFO
+/*
+  This version of malloc supports the standard SVID/XPG mallinfo
+  routine that returns a struct containing usage properties and
+  statistics. It should work on any system that has a
+  /usr/include/malloc.h defining struct mallinfo.  The main
+  declaration needed is the mallinfo struct that is returned (by-copy)
+  by mallinfo().  The malloinfo struct contains a bunch of fields that
+  are not even meaningful in this version of malloc.  These fields are
+  are instead filled by mallinfo() with other numbers that might be of
+  interest.
+
+  HAVE_USR_INCLUDE_MALLOC_H should be set if you have a
+  /usr/include/malloc.h file that includes a declaration of struct
+  mallinfo.  If so, it is included; else a compliant version is
+  declared below.  These must be precisely the same for mallinfo() to
+  work.  The original SVID version of this struct, defined on most
+  systems with mallinfo, declares all fields as ints. But some others
+  define as unsigned long. If your system defines the fields using a
+  type of different width than listed here, you MUST #include your
+  system version and #define HAVE_USR_INCLUDE_MALLOC_H.
+*/
+
+/* #define HAVE_USR_INCLUDE_MALLOC_H */
+
+#ifdef HAVE_USR_INCLUDE_MALLOC_H
+#include "/usr/include/malloc.h"
+#else /* HAVE_USR_INCLUDE_MALLOC_H */
+#ifndef STRUCT_MALLINFO_DECLARED
+/* HP-UX (and others?) redefines mallinfo unless _STRUCT_MALLINFO is defined */
+#define _STRUCT_MALLINFO
+#define STRUCT_MALLINFO_DECLARED 1
+struct mallinfo {
+  MALLINFO_FIELD_TYPE arena;    /* non-mmapped space allocated from system */
+  MALLINFO_FIELD_TYPE ordblks;  /* number of free chunks */
+  MALLINFO_FIELD_TYPE smblks;   /* always 0 */
+  MALLINFO_FIELD_TYPE hblks;    /* always 0 */
+  MALLINFO_FIELD_TYPE hblkhd;   /* space in mmapped regions */
+  MALLINFO_FIELD_TYPE usmblks;  /* maximum total allocated space */
+  MALLINFO_FIELD_TYPE fsmblks;  /* always 0 */
+  MALLINFO_FIELD_TYPE uordblks; /* total allocated space */
+  MALLINFO_FIELD_TYPE fordblks; /* total free space */
+  MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */
+};
+#endif /* STRUCT_MALLINFO_DECLARED */
+#endif /* HAVE_USR_INCLUDE_MALLOC_H */
+#endif /* NO_MALLINFO */
+
+/*
+  Try to persuade compilers to inline. The most critical functions for
+  inlining are defined as macros, so these aren't used for them.
+*/
+
+#ifndef FORCEINLINE
+  #if defined(__GNUC__)
+#define FORCEINLINE __inline __attribute__ ((always_inline))
+  #elif defined(_MSC_VER)
+    #define FORCEINLINE __forceinline
+  #endif
+#endif
+#ifndef NOINLINE
+  #if defined(__GNUC__)
+    #define NOINLINE __attribute__ ((noinline))
+  #elif defined(_MSC_VER)
+    #define NOINLINE __declspec(noinline)
+  #else
+    #define NOINLINE
+  #endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#ifndef FORCEINLINE
+ #define FORCEINLINE inline
+#endif
+#endif /* __cplusplus */
+#ifndef FORCEINLINE
+ #define FORCEINLINE
+#endif
+
+#if !ONLY_MSPACES
+
+/* ------------------- Declarations of public routines ------------------- */
+
+#ifndef USE_DL_PREFIX
+#define dlcalloc               calloc
+#define dlfree                 free
+#define dlmalloc               malloc
+#define dlmemalign             memalign
+#define dlposix_memalign       posix_memalign
+#define dlrealloc              realloc
+#define dlrealloc_in_place     realloc_in_place
+#define dlvalloc               valloc
+#define dlpvalloc              pvalloc
+#define dlmallinfo             mallinfo
+#define dlmallopt              mallopt
+#define dlmalloc_trim          malloc_trim
+#define dlmalloc_stats         malloc_stats
+#define dlmalloc_usable_size   malloc_usable_size
+#define dlmalloc_footprint     malloc_footprint
+#define dlmalloc_max_footprint malloc_max_footprint
+#define dlmalloc_footprint_limit malloc_footprint_limit
+#define dlmalloc_set_footprint_limit malloc_set_footprint_limit
+#define dlmalloc_inspect_all   malloc_inspect_all
+#define dlindependent_calloc   independent_calloc
+#define dlindependent_comalloc independent_comalloc
+#define dlbulk_free            bulk_free
+#endif /* USE_DL_PREFIX */
+
+/*
+  malloc(size_t n)
+  Returns a pointer to a newly allocated chunk of at least n bytes, or
+  null if no space is available, in which case errno is set to ENOMEM
+  on ANSI C systems.
+
+  If n is zero, malloc returns a minimum-sized chunk. (The minimum
+  size is 16 bytes on most 32bit systems, and 32 bytes on 64bit
+  systems.)  Note that size_t is an unsigned type, so calls with
+  arguments that would be negative if signed are interpreted as
+  requests for huge amounts of space, which will often fail. The
+  maximum supported value of n differs across systems, but is in all
+  cases less than the maximum representable value of a size_t.
+*/
+DLMALLOC_EXPORT void* dlmalloc(size_t);
+
+/*
+  free(void* p)
+  Releases the chunk of memory pointed to by p, that had been previously
+  allocated using malloc or a related routine such as realloc.
+  It has no effect if p is null. If p was not malloced or already
+  freed, free(p) will by default cause the current program to abort.
+*/
+DLMALLOC_EXPORT void  dlfree(void*);
+
+/*
+  calloc(size_t n_elements, size_t element_size);
+  Returns a pointer to n_elements * element_size bytes, with all locations
+  set to zero.
+*/
+DLMALLOC_EXPORT void* dlcalloc(size_t, size_t);
+
+/*
+  realloc(void* p, size_t n)
+  Returns a pointer to a chunk of size n that contains the same data
+  as does chunk p up to the minimum of (n, p's size) bytes, or null
+  if no space is available.
+
+  The returned pointer may or may not be the same as p. The algorithm
+  prefers extending p in most cases when possible, otherwise it
+  employs the equivalent of a malloc-copy-free sequence.
+
+  If p is null, realloc is equivalent to malloc.
+
+  If space is not available, realloc returns null, errno is set (if on
+  ANSI) and p is NOT freed.
+
+  if n is for fewer bytes than already held by p, the newly unused
+  space is lopped off and freed if possible.  realloc with a size
+  argument of zero (re)allocates a minimum-sized chunk.
+
+  The old unix realloc convention of allowing the last-free'd chunk
+  to be used as an argument to realloc is not supported.
+*/
+DLMALLOC_EXPORT void* dlrealloc(void*, size_t);
+
+/*
+  realloc_in_place(void* p, size_t n)
+  Resizes the space allocated for p to size n, only if this can be
+  done without moving p (i.e., only if there is adjacent space
+  available if n is greater than p's current allocated size, or n is
+  less than or equal to p's size). This may be used instead of plain
+  realloc if an alternative allocation strategy is needed upon failure
+  to expand space; for example, reallocation of a buffer that must be
+  memory-aligned or cleared. You can use realloc_in_place to trigger
+  these alternatives only when needed.
+
+  Returns p if successful; otherwise null.
+*/
+DLMALLOC_EXPORT void* dlrealloc_in_place(void*, size_t);
+
+/*
+  memalign(size_t alignment, size_t n);
+  Returns a pointer to a newly allocated chunk of n bytes, aligned
+  in accord with the alignment argument.
+
+  The alignment argument should be a power of two. If the argument is
+  not a power of two, the nearest greater power is used.
+  8-byte alignment is guaranteed by normal malloc calls, so don't
+  bother calling memalign with an argument of 8 or less.
+
+  Overreliance on memalign is a sure way to fragment space.
+*/
+DLMALLOC_EXPORT void* dlmemalign(size_t, size_t);
+
+/*
+  int posix_memalign(void** pp, size_t alignment, size_t n);
+  Allocates a chunk of n bytes, aligned in accord with the alignment
+  argument. Differs from memalign only in that it (1) assigns the
+  allocated memory to *pp rather than returning it, (2) fails and
+  returns EINVAL if the alignment is not a power of two (3) fails and
+  returns ENOMEM if memory cannot be allocated.
+*/
+DLMALLOC_EXPORT int dlposix_memalign(void**, size_t, size_t);
+
+/*
+  valloc(size_t n);
+  Equivalent to memalign(pagesize, n), where pagesize is the page
+  size of the system. If the pagesize is unknown, 4096 is used.
+*/
+DLMALLOC_EXPORT void* dlvalloc(size_t);
+
+/*
+  mallopt(int parameter_number, int parameter_value)
+  Sets tunable parameters The format is to provide a
+  (parameter-number, parameter-value) pair.  mallopt then sets the
+  corresponding parameter to the argument value if it can (i.e., so
+  long as the value is meaningful), and returns 1 if successful else
+  0.  To workaround the fact that mallopt is specified to use int,
+  not size_t parameters, the value -1 is specially treated as the
+  maximum unsigned size_t value.
+
+  SVID/XPG/ANSI defines four standard param numbers for mallopt,
+  normally defined in malloc.h.  None of these are use in this malloc,
+  so setting them has no effect. But this malloc also supports other
+  options in mallopt. See below for details.  Briefly, supported
+  parameters are as follows (listed defaults are for "typical"
+  configurations).
+
+  Symbol            param #  default    allowed param values
+  M_TRIM_THRESHOLD     -1   2*1024*1024   any   (-1 disables)
+  M_GRANULARITY        -2     page size   any power of 2 >= page size
+  M_MMAP_THRESHOLD     -3      256*1024   any   (or 0 if no MMAP support)
+*/
+DLMALLOC_EXPORT int dlmallopt(int, int);
+
+/*
+  malloc_footprint();
+  Returns the number of bytes obtained from the system.  The total
+  number of bytes allocated by malloc, realloc etc., is less than this
+  value. Unlike mallinfo, this function returns only a precomputed
+  result, so can be called frequently to monitor memory consumption.
+  Even if locks are otherwise defined, this function does not use them,
+  so results might not be up to date.
+*/
+DLMALLOC_EXPORT size_t dlmalloc_footprint(void);
+
+/*
+  malloc_max_footprint();
+  Returns the maximum number of bytes obtained from the system. This
+  value will be greater than current footprint if deallocated space
+  has been reclaimed by the system. The peak number of bytes allocated
+  by malloc, realloc etc., is less than this value. Unlike mallinfo,
+  this function returns only a precomputed result, so can be called
+  frequently to monitor memory consumption.  Even if locks are
+  otherwise defined, this function does not use them, so results might
+  not be up to date.
+*/
+DLMALLOC_EXPORT size_t dlmalloc_max_footprint(void);
+
+/*
+  malloc_footprint_limit();
+  Returns the number of bytes that the heap is allowed to obtain from
+  the system, returning the last value returned by
+  malloc_set_footprint_limit, or the maximum size_t value if
+  never set. The returned value reflects a permission. There is no
+  guarantee that this number of bytes can actually be obtained from
+  the system.
+*/
+DLMALLOC_EXPORT size_t dlmalloc_footprint_limit();
+
+/*
+  malloc_set_footprint_limit();
+  Sets the maximum number of bytes to obtain from the system, causing
+  failure returns from malloc and related functions upon attempts to
+  exceed this value. The argument value may be subject to page
+  rounding to an enforceable limit; this actual value is returned.
+  Using an argument of the maximum possible size_t effectively
+  disables checks. If the argument is less than or equal to the
+  current malloc_footprint, then all future allocations that require
+  additional system memory will fail. However, invocation cannot
+  retroactively deallocate existing used memory.
+*/
+DLMALLOC_EXPORT size_t dlmalloc_set_footprint_limit(size_t bytes);
+
+#if MALLOC_INSPECT_ALL
+/*
+  malloc_inspect_all(void(*handler)(void *start,
+                                    void *end,
+                                    size_t used_bytes,
+                                    void* callback_arg),
+                      void* arg);
+  Traverses the heap and calls the given handler for each managed
+  region, skipping all bytes that are (or may be) used for bookkeeping
+  purposes.  Traversal does not include include chunks that have been
+  directly memory mapped. Each reported region begins at the start
+  address, and continues up to but not including the end address.  The
+  first used_bytes of the region contain allocated data. If
+  used_bytes is zero, the region is unallocated. The handler is
+  invoked with the given callback argument. If locks are defined, they
+  are held during the entire traversal. It is a bad idea to invoke
+  other malloc functions from within the handler.
+
+  For example, to count the number of in-use chunks with size greater
+  than 1000, you could write:
+  static int count = 0;
+  void count_chunks(void* start, void* end, size_t used, void* arg) {
+    if (used >= 1000) ++count;
+  }
+  then:
+    malloc_inspect_all(count_chunks, NULL);
+
+  malloc_inspect_all is compiled only if MALLOC_INSPECT_ALL is defined.
+*/
+DLMALLOC_EXPORT void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*),
+                           void* arg);
+
+#endif /* MALLOC_INSPECT_ALL */
+
+#if !NO_MALLINFO
+/*
+  mallinfo()
+  Returns (by copy) a struct containing various summary statistics:
+
+  arena:     current total non-mmapped bytes allocated from system
+  ordblks:   the number of free chunks
+  smblks:    always zero.
+  hblks:     current number of mmapped regions
+  hblkhd:    total bytes held in mmapped regions
+  usmblks:   the maximum total allocated space. This will be greater
+                than current total if trimming has occurred.
+  fsmblks:   always zero
+  uordblks:  current total allocated space (normal or mmapped)
+  fordblks:  total free space
+  keepcost:  the maximum number of bytes that could ideally be released
+               back to system via malloc_trim. ("ideally" means that
+               it ignores page restrictions etc.)
+
+  Because these fields are ints, but internal bookkeeping may
+  be kept as longs, the reported values may wrap around zero and
+  thus be inaccurate.
+*/
+DLMALLOC_EXPORT struct mallinfo dlmallinfo(void);
+#endif /* NO_MALLINFO */
+
+/*
+  independent_calloc(size_t n_elements, size_t element_size, void* chunks[]);
+
+  independent_calloc is similar to calloc, but instead of returning a
+  single cleared space, it returns an array of pointers to n_elements
+  independent elements that can hold contents of size elem_size, each
+  of which starts out cleared, and can be independently freed,
+  realloc'ed etc. The elements are guaranteed to be adjacently
+  allocated (this is not guaranteed to occur with multiple callocs or
+  mallocs), which may also improve cache locality in some
+  applications.
+
+  The "chunks" argument is optional (i.e., may be null, which is
+  probably the most typical usage). If it is null, the returned array
+  is itself dynamically allocated and should also be freed when it is
+  no longer needed. Otherwise, the chunks array must be of at least
+  n_elements in length. It is filled in with the pointers to the
+  chunks.
+
+  In either case, independent_calloc returns this pointer array, or
+  null if the allocation failed.  If n_elements is zero and "chunks"
+  is null, it returns a chunk representing an array with zero elements
+  (which should be freed if not wanted).
+
+  Each element must be freed when it is no longer needed. This can be
+  done all at once using bulk_free.
+
+  independent_calloc simplifies and speeds up implementations of many
+  kinds of pools.  It may also be useful when constructing large data
+  structures that initially have a fixed number of fixed-sized nodes,
+  but the number is not known at compile time, and some of the nodes
+  may later need to be freed. For example:
+
+  struct Node { int item; struct Node* next; };
+
+  struct Node* build_list() {
+    struct Node** pool;
+    int n = read_number_of_nodes_needed();
+    if (n <= 0) return 0;
+    pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0);
+    if (pool == 0) die();
+    // organize into a linked list...
+    struct Node* first = pool[0];
+    for (i = 0; i < n-1; ++i)
+      pool[i]->next = pool[i+1];
+    free(pool);     // Can now free the array (or not, if it is needed later)
+    return first;
+  }
+*/
+DLMALLOC_EXPORT void** dlindependent_calloc(size_t, size_t, void**);
+
+/*
+  independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]);
+
+  independent_comalloc allocates, all at once, a set of n_elements
+  chunks with sizes indicated in the "sizes" array.    It returns
+  an array of pointers to these elements, each of which can be
+  independently freed, realloc'ed etc. The elements are guaranteed to
+  be adjacently allocated (this is not guaranteed to occur with
+  multiple callocs or mallocs), which may also improve cache locality
+  in some applications.
+
+  The "chunks" argument is optional (i.e., may be null). If it is null
+  the returned array is itself dynamically allocated and should also
+  be freed when it is no longer needed. Otherwise, the chunks array
+  must be of at least n_elements in length. It is filled in with the
+  pointers to the chunks.
+
+  In either case, independent_comalloc returns this pointer array, or
+  null if the allocation failed.  If n_elements is zero and chunks is
+  null, it returns a chunk representing an array with zero elements
+  (which should be freed if not wanted).
+
+  Each element must be freed when it is no longer needed. This can be
+  done all at once using bulk_free.
+
+  independent_comallac differs from independent_calloc in that each
+  element may have a different size, and also that it does not
+  automatically clear elements.
+
+  independent_comalloc can be used to speed up allocation in cases
+  where several structs or objects must always be allocated at the
+  same time.  For example:
+
+  struct Head { ... }
+  struct Foot { ... }
+
+  void send_message(char* msg) {
+    int msglen = strlen(msg);
+    size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) };
+    void* chunks[3];
+    if (independent_comalloc(3, sizes, chunks) == 0)
+      die();
+    struct Head* head = (struct Head*)(chunks[0]);
+    char*        body = (char*)(chunks[1]);
+    struct Foot* foot = (struct Foot*)(chunks[2]);
+    // ...
+  }
+
+  In general though, independent_comalloc is worth using only for
+  larger values of n_elements. For small values, you probably won't
+  detect enough difference from series of malloc calls to bother.
+
+  Overuse of independent_comalloc can increase overall memory usage,
+  since it cannot reuse existing noncontiguous small chunks that
+  might be available for some of the elements.
+*/
+DLMALLOC_EXPORT void** dlindependent_comalloc(size_t, size_t*, void**);
+
+/*
+  bulk_free(void* array[], size_t n_elements)
+  Frees and clears (sets to null) each non-null pointer in the given
+  array.  This is likely to be faster than freeing them one-by-one.
+  If footers are used, pointers that have been allocated in different
+  mspaces are not freed or cleared, and the count of all such pointers
+  is returned.  For large arrays of pointers with poor locality, it
+  may be worthwhile to sort this array before calling bulk_free.
+*/
+DLMALLOC_EXPORT size_t  dlbulk_free(void**, size_t n_elements);
+
+/*
+  pvalloc(size_t n);
+  Equivalent to valloc(minimum-page-that-holds(n)), that is,
+  round up n to nearest pagesize.
+ */
+DLMALLOC_EXPORT void*  dlpvalloc(size_t);
+
+/*
+  malloc_trim(size_t pad);
+
+  If possible, gives memory back to the system (via negative arguments
+  to sbrk) if there is unused memory at the `high' end of the malloc
+  pool or in unused MMAP segments. You can call this after freeing
+  large blocks of memory to potentially reduce the system-level memory
+  requirements of a program. However, it cannot guarantee to reduce
+  memory. Under some allocation patterns, some large free blocks of
+  memory will be locked between two used chunks, so they cannot be
+  given back to the system.
+
+  The `pad' argument to malloc_trim represents the amount of free
+  trailing space to leave untrimmed. If this argument is zero, only
+  the minimum amount of memory to maintain internal data structures
+  will be left. Non-zero arguments can be supplied to maintain enough
+  trailing space to service future expected allocations without having
+  to re-obtain memory from the system.
+
+  Malloc_trim returns 1 if it actually released any memory, else 0.
+*/
+DLMALLOC_EXPORT int  dlmalloc_trim(size_t);
+
+/*
+  malloc_stats();
+  Prints on stderr the amount of space obtained from the system (both
+  via sbrk and mmap), the maximum amount (which may be more than
+  current if malloc_trim and/or munmap got called), and the current
+  number of bytes allocated via malloc (or realloc, etc) but not yet
+  freed. Note that this is the number of bytes allocated, not the
+  number requested. It will be larger than the number requested
+  because of alignment and bookkeeping overhead. Because it includes
+  alignment wastage as being in use, this figure may be greater than
+  zero even when no user-level chunks are allocated.
+
+  The reported current and maximum system memory can be inaccurate if
+  a program makes other calls to system memory allocation functions
+  (normally sbrk) outside of malloc.
+
+  malloc_stats prints only the most commonly interesting statistics.
+  More information can be obtained by calling mallinfo.
+*/
+DLMALLOC_EXPORT void  dlmalloc_stats(void);
+
+/*
+  malloc_usable_size(void* p);
+
+  Returns the number of bytes you can actually use in
+  an allocated chunk, which may be more than you requested (although
+  often not) due to alignment and minimum size constraints.
+  You can use this many bytes without worrying about
+  overwriting other allocated objects. This is not a particularly great
+  programming practice. malloc_usable_size can be more useful in
+  debugging and assertions, for example:
+
+  p = malloc(n);
+  assert(malloc_usable_size(p) >= 256);
+*/
+size_t dlmalloc_usable_size(void*);
+
+#endif /* ONLY_MSPACES */
+
+#if MSPACES
+
+/*
+  mspace is an opaque type representing an independent
+  region of space that supports mspace_malloc, etc.
+*/
+typedef void* mspace;
+
+/*
+  create_mspace creates and returns a new independent space with the
+  given initial capacity, or, if 0, the default granularity size.  It
+  returns null if there is no system memory available to create the
+  space.  If argument locked is non-zero, the space uses a separate
+  lock to control access. The capacity of the space will grow
+  dynamically as needed to service mspace_malloc requests.  You can
+  control the sizes of incremental increases of this space by
+  compiling with a different DEFAULT_GRANULARITY or dynamically
+  setting with mallopt(M_GRANULARITY, value).
+*/
+DLMALLOC_EXPORT mspace create_mspace(size_t capacity, int locked);
+
+/*
+  destroy_mspace destroys the given space, and attempts to return all
+  of its memory back to the system, returning the total number of
+  bytes freed. After destruction, the results of access to all memory
+  used by the space become undefined.
+*/
+DLMALLOC_EXPORT size_t destroy_mspace(mspace msp);
+
+/*
+  create_mspace_with_base uses the memory supplied as the initial base
+  of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this
+  space is used for bookkeeping, so the capacity must be at least this
+  large. (Otherwise 0 is returned.) When this initial space is
+  exhausted, additional memory will be obtained from the system.
+  Destroying this space will deallocate all additionally allocated
+  space (if possible) but not the initial base.
+*/
+DLMALLOC_EXPORT mspace create_mspace_with_base(void* base, size_t capacity, int locked);
+
+/*
+  mspace_track_large_chunks controls whether requests for large chunks
+  are allocated in their own untracked mmapped regions, separate from
+  others in this mspace. By default large chunks are not tracked,
+  which reduces fragmentation. However, such chunks are not
+  necessarily released to the system upon destroy_mspace.  Enabling
+  tracking by setting to true may increase fragmentation, but avoids
+  leakage when relying on destroy_mspace to release all memory
+  allocated using this space.  The function returns the previous
+  setting.
+*/
+DLMALLOC_EXPORT int mspace_track_large_chunks(mspace msp, int enable);
+
+
+/*
+  mspace_malloc behaves as malloc, but operates within
+  the given space.
+*/
+DLMALLOC_EXPORT void* mspace_malloc(mspace msp, size_t bytes);
+
+/*
+  mspace_free behaves as free, but operates within
+  the given space.
+
+  If compiled with FOOTERS==1, mspace_free is not actually needed.
+  free may be called instead of mspace_free because freed chunks from
+  any space are handled by their originating spaces.
+*/
+DLMALLOC_EXPORT void mspace_free(mspace msp, void* mem);
+
+/*
+  mspace_realloc behaves as realloc, but operates within
+  the given space.
+
+  If compiled with FOOTERS==1, mspace_realloc is not actually
+  needed.  realloc may be called instead of mspace_realloc because
+  realloced chunks from any space are handled by their originating
+  spaces.
+*/
+DLMALLOC_EXPORT void* mspace_realloc(mspace msp, void* mem, size_t newsize);
+
+/*
+  mspace_calloc behaves as calloc, but operates within
+  the given space.
+*/
+DLMALLOC_EXPORT void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size);
+
+/*
+  mspace_memalign behaves as memalign, but operates within
+  the given space.
+*/
+DLMALLOC_EXPORT void* mspace_memalign(mspace msp, size_t alignment, size_t bytes);
+
+/*
+  mspace_independent_calloc behaves as independent_calloc, but
+  operates within the given space.
+*/
+DLMALLOC_EXPORT void** mspace_independent_calloc(mspace msp, size_t n_elements,
+                                 size_t elem_size, void* chunks[]);
+
+/*
+  mspace_independent_comalloc behaves as independent_comalloc, but
+  operates within the given space.
+*/
+DLMALLOC_EXPORT void** mspace_independent_comalloc(mspace msp, size_t n_elements,
+                                   size_t sizes[], void* chunks[]);
+
+/*
+  mspace_footprint() returns the number of bytes obtained from the
+  system for this space.
+*/
+DLMALLOC_EXPORT size_t mspace_footprint(mspace msp);
+
+/*
+  mspace_max_footprint() returns the peak number of bytes obtained from the
+  system for this space.
+*/
+DLMALLOC_EXPORT size_t mspace_max_footprint(mspace msp);
+
+
+#if !NO_MALLINFO
+/*
+  mspace_mallinfo behaves as mallinfo, but reports properties of
+  the given space.
+*/
+DLMALLOC_EXPORT struct mallinfo mspace_mallinfo(mspace msp);
+#endif /* NO_MALLINFO */
+
+/*
+  malloc_usable_size(void* p) behaves the same as malloc_usable_size;
+*/
+DLMALLOC_EXPORT size_t mspace_usable_size(const void* mem);
+
+/*
+  mspace_malloc_stats behaves as malloc_stats, but reports
+  properties of the given space.
+*/
+DLMALLOC_EXPORT void mspace_malloc_stats(mspace msp);
+
+/*
+  mspace_trim behaves as malloc_trim, but
+  operates within the given space.
+*/
+DLMALLOC_EXPORT int mspace_trim(mspace msp, size_t pad);
+
+/*
+  An alias for mallopt.
+*/
+DLMALLOC_EXPORT int mspace_mallopt(int, int);
+
+#endif /* MSPACES */
+
+#ifdef __cplusplus
+}  /* end of extern "C" */
+#endif /* __cplusplus */
+
+/*
+  ========================================================================
+  To make a fully customizable malloc.h header file, cut everything
+  above this line, put into file malloc.h, edit to suit, and #include it
+  on the next line, as well as in programs that use this malloc.
+  ========================================================================
+*/
+
+/* #include "malloc.h" */
+
+/*------------------------------ internal #includes ---------------------- */
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4146 ) /* no "unsigned" warnings */
+#endif /* _MSC_VER */
+#if !NO_MALLOC_STATS
+#include <stdio.h>       /* for printing in malloc_stats */
+#endif /* NO_MALLOC_STATS */
+#ifndef LACKS_ERRNO_H
+#include <errno.h>       /* for MALLOC_FAILURE_ACTION */
+#endif /* LACKS_ERRNO_H */
+#ifdef DEBUG
+#if ABORT_ON_ASSERT_FAILURE
+#undef assert
+#define assert(x) if(!(x)) ABORT
+#else /* ABORT_ON_ASSERT_FAILURE */
+#include <assert.h>
+#endif /* ABORT_ON_ASSERT_FAILURE */
+#else  /* DEBUG */
+#ifndef assert
+#define assert(x)
+#endif
+#define DEBUG 0
+#endif /* DEBUG */
+#if !defined(WIN32) && !defined(LACKS_TIME_H)
+#include <time.h>        /* for magic initialization */
+#endif /* WIN32 */
+#ifndef LACKS_STDLIB_H
+#include <stdlib.h>      /* for abort() */
+#endif /* LACKS_STDLIB_H */
+#ifndef LACKS_STRING_H
+#include <string.h>      /* for memset etc */
+#endif  /* LACKS_STRING_H */
+#if USE_BUILTIN_FFS
+#ifndef LACKS_STRINGS_H
+#include <strings.h>     /* for ffs */
+#endif /* LACKS_STRINGS_H */
+#endif /* USE_BUILTIN_FFS */
+#if HAVE_MMAP
+#ifndef LACKS_SYS_MMAN_H
+/* On some versions of linux, mremap decl in mman.h needs __USE_GNU set */
+#if (defined(linux) && !defined(__USE_GNU))
+#define __USE_GNU 1
+#include <sys/mman.h>    /* for mmap */
+#undef __USE_GNU
+#else
+#include <sys/mman.h>    /* for mmap */
+#endif /* linux */
+#endif /* LACKS_SYS_MMAN_H */
+#ifndef LACKS_FCNTL_H
+#include <fcntl.h>
+#endif /* LACKS_FCNTL_H */
+#endif /* HAVE_MMAP */
+#ifndef LACKS_UNISTD_H
+#include <unistd.h>     /* for sbrk, sysconf */
+#else /* LACKS_UNISTD_H */
+#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
+extern void*     sbrk(ptrdiff_t);
+#endif /* FreeBSD etc */
+#endif /* LACKS_UNISTD_H */
+
+/* Declarations for locking */
+#if USE_LOCKS
+#ifndef WIN32
+#if defined (__SVR4) && defined (__sun)  /* solaris */
+#include <thread.h>
+#elif !defined(LACKS_SCHED_H)
+#include <sched.h>
+#endif /* solaris or LACKS_SCHED_H */
+#if (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0) || !USE_SPIN_LOCKS
+#include <pthread.h>
+#endif /* USE_RECURSIVE_LOCKS ... */
+#elif defined(_MSC_VER)
+#ifndef _M_AMD64
+/* These are already defined on AMD64 builds */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+LONG __cdecl _InterlockedCompareExchange(LONG volatile *Dest, LONG Exchange, LONG Comp);
+LONG __cdecl _InterlockedExchange(LONG volatile *Target, LONG Value);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _M_AMD64 */
+#pragma intrinsic (_InterlockedCompareExchange)
+#pragma intrinsic (_InterlockedExchange)
+#define interlockedcompareexchange _InterlockedCompareExchange
+#define interlockedexchange _InterlockedExchange
+#elif defined(WIN32) && defined(__GNUC__)
+#define interlockedcompareexchange(a, b, c) __sync_val_compare_and_swap(a, c, b)
+#define interlockedexchange __sync_lock_test_and_set
+#endif /* Win32 */
+#else /* USE_LOCKS */
+#endif /* USE_LOCKS */
+
+#ifndef LOCK_AT_FORK
+#define LOCK_AT_FORK 0
+#endif
+
+/* Declarations for bit scanning on win32 */
+#if defined(_MSC_VER) && _MSC_VER>=1300
+#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+unsigned char _BitScanForward(unsigned long *index, unsigned long mask);
+unsigned char _BitScanReverse(unsigned long *index, unsigned long mask);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#define BitScanForward _BitScanForward
+#define BitScanReverse _BitScanReverse
+#pragma intrinsic(_BitScanForward)
+#pragma intrinsic(_BitScanReverse)
+#endif /* BitScanForward */
+#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */
+
+#ifndef WIN32
+#ifndef malloc_getpagesize
+#  ifdef _SC_PAGESIZE         /* some SVR4 systems omit an underscore */
+#    ifndef _SC_PAGE_SIZE
+#      define _SC_PAGE_SIZE _SC_PAGESIZE
+#    endif
+#  endif
+#  ifdef _SC_PAGE_SIZE
+#    define malloc_getpagesize sysconf(_SC_PAGE_SIZE)
+#  else
+#    if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE)
+       extern size_t getpagesize();
+#      define malloc_getpagesize getpagesize()
+#    else
+#      ifdef WIN32 /* use supplied emulation of getpagesize */
+#        define malloc_getpagesize getpagesize()
+#      else
+#        ifndef LACKS_SYS_PARAM_H
+#          include <sys/param.h>
+#        endif
+#        ifdef EXEC_PAGESIZE
+#          define malloc_getpagesize EXEC_PAGESIZE
+#        else
+#          ifdef NBPG
+#            ifndef CLSIZE
+#              define malloc_getpagesize NBPG
+#            else
+#              define malloc_getpagesize (NBPG * CLSIZE)
+#            endif
+#          else
+#            ifdef NBPC
+#              define malloc_getpagesize NBPC
+#            else
+#              ifdef PAGESIZE
+#                define malloc_getpagesize PAGESIZE
+#              else /* just guess */
+#                define malloc_getpagesize ((size_t)4096U)
+#              endif
+#            endif
+#          endif
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+#endif
+
+/* ------------------- size_t and alignment properties -------------------- */
+
+/* The byte and bit size of a size_t */
+#define SIZE_T_SIZE         (sizeof(size_t))
+#define SIZE_T_BITSIZE      (sizeof(size_t) << 3)
+
+/* Some constants coerced to size_t */
+/* Annoying but necessary to avoid errors on some platforms */
+#define SIZE_T_ZERO         ((size_t)0)
+#define SIZE_T_ONE          ((size_t)1)
+#define SIZE_T_TWO          ((size_t)2)
+#define SIZE_T_FOUR         ((size_t)4)
+#define TWO_SIZE_T_SIZES    (SIZE_T_SIZE<<1)
+#define FOUR_SIZE_T_SIZES   (SIZE_T_SIZE<<2)
+#define SIX_SIZE_T_SIZES    (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES)
+#define HALF_MAX_SIZE_T     (MAX_SIZE_T / 2U)
+
+/* The bit mask value corresponding to MALLOC_ALIGNMENT */
+#define CHUNK_ALIGN_MASK    (MALLOC_ALIGNMENT - SIZE_T_ONE)
+
+/* True if address a has acceptable alignment */
+#define is_aligned(A)       (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
+
+/* the number of bytes to offset an address to align it */
+#define align_offset(A)\
+ ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
+  ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
+
+/* -------------------------- MMAP preliminaries ------------------------- */
+
+/*
+   If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and
+   checks to fail so compiler optimizer can delete code rather than
+   using so many "#if"s.
+*/
+
+
+/* MORECORE and MMAP must return MFAIL on failure */
+#define MFAIL                ((void*)(MAX_SIZE_T))
+#define CMFAIL               ((char*)(MFAIL)) /* defined for convenience */
+
+#if HAVE_MMAP
+
+#ifndef WIN32
+#define MUNMAP_DEFAULT(a, s)  munmap((a), (s))
+#define MMAP_PROT            (PROT_READ|PROT_WRITE)
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+#define MAP_ANONYMOUS        MAP_ANON
+#endif /* MAP_ANON */
+#ifdef MAP_ANONYMOUS
+#define MMAP_FLAGS           (MAP_PRIVATE|MAP_ANONYMOUS)
+#define MMAP_DEFAULT(s)       mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0)
+#else /* MAP_ANONYMOUS */
+/*
+   Nearly all versions of mmap support MAP_ANONYMOUS, so the following
+   is unlikely to be needed, but is supplied just in case.
+*/
+#define MMAP_FLAGS           (MAP_PRIVATE)
+static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */
+#define MMAP_DEFAULT(s) ((dev_zero_fd < 0) ? \
+           (dev_zero_fd = open("/dev/zero", O_RDWR), \
+            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \
+            mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0))
+#endif /* MAP_ANONYMOUS */
+
+#define DIRECT_MMAP_DEFAULT(s) MMAP_DEFAULT(s)
+
+#else /* WIN32 */
+
+/* Win32 MMAP via VirtualAlloc */
+static FORCEINLINE void* win32mmap(size_t size) {
+  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
+  return (ptr != 0)? ptr: MFAIL;
+}
+
+/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */
+static FORCEINLINE void* win32direct_mmap(size_t size) {
+  void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
+                           PAGE_READWRITE);
+  return (ptr != 0)? ptr: MFAIL;
+}
+
+/* This function supports releasing coalesed segments */
+static FORCEINLINE int win32munmap(void* ptr, size_t size) {
+  MEMORY_BASIC_INFORMATION minfo;
+  char* cptr = (char*)ptr;
+  while (size) {
+    if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0)
+      return -1;
+    if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr ||
+        minfo.State != MEM_COMMIT || minfo.RegionSize > size)
+      return -1;
+    if (VirtualFree(cptr, 0, MEM_RELEASE) == 0)
+      return -1;
+    cptr += minfo.RegionSize;
+    size -= minfo.RegionSize;
+  }
+  return 0;
+}
+
+#define MMAP_DEFAULT(s)             win32mmap(s)
+#define MUNMAP_DEFAULT(a, s)        win32munmap((a), (s))
+#define DIRECT_MMAP_DEFAULT(s)      win32direct_mmap(s)
+#endif /* WIN32 */
+#endif /* HAVE_MMAP */
+
+#if HAVE_MREMAP
+#ifndef WIN32
+#define MREMAP_DEFAULT(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv))
+#endif /* WIN32 */
+#endif /* HAVE_MREMAP */
+
+/**
+ * Define CALL_MORECORE
+ */
+#if HAVE_MORECORE
+    #ifdef MORECORE
+        #define CALL_MORECORE(S)    MORECORE(S)
+    #else  /* MORECORE */
+        #define CALL_MORECORE(S)    MORECORE_DEFAULT(S)
+    #endif /* MORECORE */
+#else  /* HAVE_MORECORE */
+    #define CALL_MORECORE(S)        MFAIL
+#endif /* HAVE_MORECORE */
+
+/**
+ * Define CALL_MMAP/CALL_MUNMAP/CALL_DIRECT_MMAP
+ */
+#if HAVE_MMAP
+    #define USE_MMAP_BIT            (SIZE_T_ONE)
+
+    #ifdef MMAP
+        #define CALL_MMAP(s)        MMAP(s)
+    #else /* MMAP */
+        #define CALL_MMAP(s)        MMAP_DEFAULT(s)
+    #endif /* MMAP */
+    #ifdef MUNMAP
+        #define CALL_MUNMAP(a, s)   MUNMAP((a), (s))
+    #else /* MUNMAP */
+        #define CALL_MUNMAP(a, s)   MUNMAP_DEFAULT((a), (s))
+    #endif /* MUNMAP */
+    #ifdef DIRECT_MMAP
+        #define CALL_DIRECT_MMAP(s) DIRECT_MMAP(s)
+    #else /* DIRECT_MMAP */
+        #define CALL_DIRECT_MMAP(s) DIRECT_MMAP_DEFAULT(s)
+    #endif /* DIRECT_MMAP */
+#else  /* HAVE_MMAP */
+    #define USE_MMAP_BIT            (SIZE_T_ZERO)
+
+    #define MMAP(s)                 MFAIL
+    #define MUNMAP(a, s)            (-1)
+    #define DIRECT_MMAP(s)          MFAIL
+    #define CALL_DIRECT_MMAP(s)     DIRECT_MMAP(s)
+    #define CALL_MMAP(s)            MMAP(s)
+    #define CALL_MUNMAP(a, s)       MUNMAP((a), (s))
+#endif /* HAVE_MMAP */
+
+/**
+ * Define CALL_MREMAP
+ */
+#if HAVE_MMAP && HAVE_MREMAP
+    #ifdef MREMAP
+        #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP((addr), (osz), (nsz), (mv))
+    #else /* MREMAP */
+        #define CALL_MREMAP(addr, osz, nsz, mv) MREMAP_DEFAULT((addr), (osz), (nsz), (mv))
+    #endif /* MREMAP */
+#else  /* HAVE_MMAP && HAVE_MREMAP */
+    #define CALL_MREMAP(addr, osz, nsz, mv)     MFAIL
+#endif /* HAVE_MMAP && HAVE_MREMAP */
+
+/* mstate bit set if continguous morecore disabled or failed */
+#define USE_NONCONTIGUOUS_BIT (4U)
+
+/* segment bit set in create_mspace_with_base */
+#define EXTERN_BIT            (8U)
+
+
+/* --------------------------- Lock preliminaries ------------------------ */
+
+/*
+  When locks are defined, there is one global lock, plus
+  one per-mspace lock.
+
+  The global lock_ensures that mparams.magic and other unique
+  mparams values are initialized only once. It also protects
+  sequences of calls to MORECORE.  In many cases sys_alloc requires
+  two calls, that should not be interleaved with calls by other
+  threads.  This does not protect against direct calls to MORECORE
+  by other threads not using this lock, so there is still code to
+  cope the best we can on interference.
+
+  Per-mspace locks surround calls to malloc, free, etc.
+  By default, locks are simple non-reentrant mutexes.
+
+  Because lock-protected regions generally have bounded times, it is
+  OK to use the supplied simple spinlocks. Spinlocks are likely to
+  improve performance for lightly contended applications, but worsen
+  performance under heavy contention.
+
+  If USE_LOCKS is > 1, the definitions of lock routines here are
+  bypassed, in which case you will need to define the type MLOCK_T,
+  and at least INITIAL_LOCK, DESTROY_LOCK, ACQUIRE_LOCK, RELEASE_LOCK
+  and TRY_LOCK.  You must also declare a
+    static MLOCK_T malloc_global_mutex = { initialization values };.
+
+*/
+
+#if !USE_LOCKS
+#define USE_LOCK_BIT               (0U)
+#define INITIAL_LOCK(l)            (0)
+#define DESTROY_LOCK(l)            (0)
+#define ACQUIRE_MALLOC_GLOBAL_LOCK()
+#define RELEASE_MALLOC_GLOBAL_LOCK()
+
+#else
+#if USE_LOCKS > 1
+/* -----------------------  User-defined locks ------------------------ */
+/* Define your own lock implementation here */
+/* #define INITIAL_LOCK(lk)  ... */
+/* #define DESTROY_LOCK(lk)  ... */
+/* #define ACQUIRE_LOCK(lk)  ... */
+/* #define RELEASE_LOCK(lk)  ... */
+/* #define TRY_LOCK(lk) ... */
+/* static MLOCK_T malloc_global_mutex = ... */
+
+#elif USE_SPIN_LOCKS
+
+/* First, define CAS_LOCK and CLEAR_LOCK on ints */
+/* Note CAS_LOCK defined to return 0 on success */
+
+#if defined(__GNUC__)&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1))
+#define CAS_LOCK(sl)     __sync_lock_test_and_set(sl, 1)
+#define CLEAR_LOCK(sl)   __sync_lock_release(sl)
+
+#elif (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))
+/* Custom spin locks for older gcc on x86 */
+static FORCEINLINE int x86_cas_lock(int *sl) {
+  int ret;
+  int val = 1;
+  int cmp = 0;
+  __asm__ __volatile__  ("lock; cmpxchgl %1, %2"
+                         : "=a" (ret)
+                         : "r" (val), "m" (*(sl)), "0"(cmp)
+                         : "memory", "cc");
+  return ret;
+}
+
+static FORCEINLINE void x86_clear_lock(int* sl) {
+  assert(*sl != 0);
+  int prev = 0;
+  int ret;
+  __asm__ __volatile__ ("lock; xchgl %0, %1"
+                        : "=r" (ret)
+                        : "m" (*(sl)), "0"(prev)
+                        : "memory");
+}
+
+#define CAS_LOCK(sl)     x86_cas_lock(sl)
+#define CLEAR_LOCK(sl)   x86_clear_lock(sl)
+
+#else /* Win32 MSC */
+#define CAS_LOCK(sl)     interlockedexchange(sl, (LONG)1)
+#define CLEAR_LOCK(sl)   interlockedexchange (sl, (LONG)0)
+
+#endif /* ... gcc spins locks ... */
+
+/* How to yield for a spin lock */
+#define SPINS_PER_YIELD       63
+#if defined(_MSC_VER)
+#define SLEEP_EX_DURATION     50 /* delay for yield/sleep */
+#define SPIN_LOCK_YIELD  SleepEx(SLEEP_EX_DURATION, FALSE)
+#elif defined (__SVR4) && defined (__sun) /* solaris */
+#define SPIN_LOCK_YIELD   thr_yield();
+#elif !defined(LACKS_SCHED_H)
+#define SPIN_LOCK_YIELD   sched_yield();
+#else
+#define SPIN_LOCK_YIELD
+#endif /* ... yield ... */
+
+#if !defined(USE_RECURSIVE_LOCKS) || USE_RECURSIVE_LOCKS == 0
+/* Plain spin locks use single word (embedded in malloc_states) */
+static int spin_acquire_lock(int *sl) {
+  int spins = 0;
+  while (*(volatile int *)sl != 0 || CAS_LOCK(sl)) {
+    if ((++spins & SPINS_PER_YIELD) == 0) {
+      SPIN_LOCK_YIELD;
+    }
+  }
+  return 0;
+}
+
+#define MLOCK_T               int
+#define TRY_LOCK(sl)          !CAS_LOCK(sl)
+#define RELEASE_LOCK(sl)      CLEAR_LOCK(sl)
+#define ACQUIRE_LOCK(sl)      (CAS_LOCK(sl)? spin_acquire_lock(sl) : 0)
+#define INITIAL_LOCK(sl)      (*sl = 0)
+#define DESTROY_LOCK(sl)      (0)
+static MLOCK_T malloc_global_mutex = 0;
+
+#else /* USE_RECURSIVE_LOCKS */
+/* types for lock owners */
+#ifdef WIN32
+#define THREAD_ID_T           DWORD
+#define CURRENT_THREAD        GetCurrentThreadId()
+#define EQ_OWNER(X,Y)         ((X) == (Y))
+#else
+/*
+  Note: the following assume that pthread_t is a type that can be
+  initialized to (casted) zero. If this is not the case, you will need to
+  somehow redefine these or not use spin locks.
+*/
+#define THREAD_ID_T           pthread_t
+#define CURRENT_THREAD        pthread_self()
+#define EQ_OWNER(X,Y)         pthread_equal(X, Y)
+#endif
+
+struct malloc_recursive_lock {
+  int sl;
+  unsigned int c;
+  THREAD_ID_T threadid;
+};
+
+#define MLOCK_T  struct malloc_recursive_lock
+static MLOCK_T malloc_global_mutex = { 0, 0, (THREAD_ID_T)0};
+
+static FORCEINLINE void recursive_release_lock(MLOCK_T *lk) {
+  assert(lk->sl != 0);
+  if (--lk->c == 0) {
+    CLEAR_LOCK(&lk->sl);
+  }
+}
+
+static FORCEINLINE int recursive_acquire_lock(MLOCK_T *lk) {
+  THREAD_ID_T mythreadid = CURRENT_THREAD;
+  int spins = 0;
+  for (;;) {
+    if (*((volatile int *)(&lk->sl)) == 0) {
+      if (!CAS_LOCK(&lk->sl)) {
+        lk->threadid = mythreadid;
+        lk->c = 1;
+        return 0;
+      }
+    }
+    else if (EQ_OWNER(lk->threadid, mythreadid)) {
+      ++lk->c;
+      return 0;
+    }
+    if ((++spins & SPINS_PER_YIELD) == 0) {
+      SPIN_LOCK_YIELD;
+    }
+  }
+}
+
+static FORCEINLINE int recursive_try_lock(MLOCK_T *lk) {
+  THREAD_ID_T mythreadid = CURRENT_THREAD;
+  if (*((volatile int *)(&lk->sl)) == 0) {
+    if (!CAS_LOCK(&lk->sl)) {
+      lk->threadid = mythreadid;
+      lk->c = 1;
+      return 1;
+    }
+  }
+  else if (EQ_OWNER(lk->threadid, mythreadid)) {
+    ++lk->c;
+    return 1;
+  }
+  return 0;
+}
+
+#define RELEASE_LOCK(lk)      recursive_release_lock(lk)
+#define TRY_LOCK(lk)          recursive_try_lock(lk)
+#define ACQUIRE_LOCK(lk)      recursive_acquire_lock(lk)
+#define INITIAL_LOCK(lk)      ((lk)->threadid = (THREAD_ID_T)0, (lk)->sl = 0, (lk)->c = 0)
+#define DESTROY_LOCK(lk)      (0)
+#endif /* USE_RECURSIVE_LOCKS */
+
+#elif defined(WIN32) /* Win32 critical sections */
+#define MLOCK_T               CRITICAL_SECTION
+#define ACQUIRE_LOCK(lk)      (EnterCriticalSection(lk), 0)
+#define RELEASE_LOCK(lk)      LeaveCriticalSection(lk)
+#define TRY_LOCK(lk)          TryEnterCriticalSection(lk)
+#define INITIAL_LOCK(lk)      (!InitializeCriticalSectionAndSpinCount((lk), 0x80000000|4000))
+#define DESTROY_LOCK(lk)      (DeleteCriticalSection(lk), 0)
+#define NEED_GLOBAL_LOCK_INIT
+
+static MLOCK_T malloc_global_mutex;
+static volatile LONG malloc_global_mutex_status;
+
+/* Use spin loop to initialize global lock */
+static void init_malloc_global_mutex() {
+  for (;;) {
+    long stat = malloc_global_mutex_status;
+    if (stat > 0)
+      return;
+    /* transition to < 0 while initializing, then to > 0) */
+    if (stat == 0 &&
+        interlockedcompareexchange(&malloc_global_mutex_status, (LONG)-1, (LONG)0) == 0) {
+      InitializeCriticalSection(&malloc_global_mutex);
+      interlockedexchange(&malloc_global_mutex_status, (LONG)1);
+      return;
+    }
+    SleepEx(0, FALSE);
+  }
+}
+
+#else /* pthreads-based locks */
+#define MLOCK_T               pthread_mutex_t
+#define ACQUIRE_LOCK(lk)      pthread_mutex_lock(lk)
+#define RELEASE_LOCK(lk)      pthread_mutex_unlock(lk)
+#define TRY_LOCK(lk)          (!pthread_mutex_trylock(lk))
+#define INITIAL_LOCK(lk)      pthread_init_lock(lk)
+#define DESTROY_LOCK(lk)      pthread_mutex_destroy(lk)
+
+#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0 && defined(linux) && !defined(PTHREAD_MUTEX_RECURSIVE)
+/* Cope with old-style linux recursive lock initialization by adding */
+/* skipped internal declaration from pthread.h */
+extern int pthread_mutexattr_setkind_np __P ((pthread_mutexattr_t *__attr,
+                                              int __kind));
+#define PTHREAD_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
+#define pthread_mutexattr_settype(x,y) pthread_mutexattr_setkind_np(x,y)
+#endif /* USE_RECURSIVE_LOCKS ... */
+
+static MLOCK_T malloc_global_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static int pthread_init_lock (MLOCK_T *lk) {
+  pthread_mutexattr_t attr;
+  if (pthread_mutexattr_init(&attr)) return 1;
+#if defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0
+  if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1;
+#endif
+  if (pthread_mutex_init(lk, &attr)) return 1;
+  if (pthread_mutexattr_destroy(&attr)) return 1;
+  return 0;
+}
+
+#endif /* ... lock types ... */
+
+/* Common code for all lock types */
+#define USE_LOCK_BIT               (2U)
+
+#ifndef ACQUIRE_MALLOC_GLOBAL_LOCK
+#define ACQUIRE_MALLOC_GLOBAL_LOCK()  ACQUIRE_LOCK(&malloc_global_mutex);
+#endif
+
+#ifndef RELEASE_MALLOC_GLOBAL_LOCK
+#define RELEASE_MALLOC_GLOBAL_LOCK()  RELEASE_LOCK(&malloc_global_mutex);
+#endif
+
+#endif /* USE_LOCKS */
+
+/* -----------------------  Chunk representations ------------------------ */
+
+/*
+  (The following includes lightly edited explanations by Colin Plumb.)
+
+  The malloc_chunk declaration below is misleading (but accurate and
+  necessary).  It declares a "view" into memory allowing access to
+  necessary fields at known offsets from a given base.
+
+  Chunks of memory are maintained using a `boundary tag' method as
+  originally described by Knuth.  (See the paper by Paul Wilson
+  ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such
+  techniques.)  Sizes of free chunks are stored both in the front of
+  each chunk and at the end.  This makes consolidating fragmented
+  chunks into bigger chunks fast.  The head fields also hold bits
+  representing whether chunks are free or in use.
+
+  Here are some pictures to make it clearer.  They are "exploded" to
+  show that the state of a chunk can be thought of as extending from
+  the high 31 bits of the head field of its header through the
+  prev_foot and PINUSE_BIT bit of the following chunk header.
+
+  A chunk that's in use looks like:
+
+   chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+           | Size of previous chunk (if P = 0)                             |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
+         | Size of this chunk                                         1| +-+
+   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               |
+         +-                                                             -+
+         |                                                               |
+         +-                                                             -+
+         |                                                               :
+         +-      size - sizeof(size_t) available payload bytes          -+
+         :                                                               |
+ chunk-> +-                                                             -+
+         |                                                               |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1|
+       | Size of next chunk (may or may not be in use)               | +-+
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+    And if it's free, it looks like this:
+
+   chunk-> +-                                                             -+
+           | User payload (must be in use, or we would have merged!)       |
+           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P|
+         | Size of this chunk                                         0| +-+
+   mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Next pointer                                                  |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Prev pointer                                                  |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         |                                                               :
+         +-      size - sizeof(struct chunk) unused bytes               -+
+         :                                                               |
+ chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+         | Size of this chunk                                            |
+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0|
+       | Size of next chunk (must be in use, or we would have merged)| +-+
+ mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+       |                                                               :
+       +- User payload                                                -+
+       :                                                               |
+       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+                                                                     |0|
+                                                                     +-+
+  Note that since we always merge adjacent free chunks, the chunks
+  adjacent to a free chunk must be in use.
+
+  Given a pointer to a chunk (which can be derived trivially from the
+  payload pointer) we can, in O(1) time, find out whether the adjacent
+  chunks are free, and if so, unlink them from the lists that they
+  are on and merge them with the current chunk.
+
+  Chunks always begin on even word boundaries, so the mem portion
+  (which is returned to the user) is also on an even word boundary, and
+  thus at least double-word aligned.
+
+  The P (PINUSE_BIT) bit, stored in the unused low-order bit of the
+  chunk size (which is always a multiple of two words), is an in-use
+  bit for the *previous* chunk.  If that bit is *clear*, then the
+  word before the current chunk size contains the previous chunk
+  size, and can be used to find the front of the previous chunk.
+  The very first chunk allocated always has this bit set, preventing
+  access to non-existent (or non-owned) memory. If pinuse is set for
+  any given chunk, then you CANNOT determine the size of the
+  previous chunk, and might even get a memory addressing fault when
+  trying to do so.
+
+  The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of
+  the chunk size redundantly records whether the current chunk is
+  inuse (unless the chunk is mmapped). This redundancy enables usage
+  checks within free and realloc, and reduces indirection when freeing
+  and consolidating chunks.
+
+  Each freshly allocated chunk must have both cinuse and pinuse set.
+  That is, each allocated chunk borders either a previously allocated
+  and still in-use chunk, or the base of its memory arena. This is
+  ensured by making all allocations from the `lowest' part of any
+  found chunk.  Further, no free chunk physically borders another one,
+  so each free chunk is known to be preceded and followed by either
+  inuse chunks or the ends of memory.
+
+  Note that the `foot' of the current chunk is actually represented
+  as the prev_foot of the NEXT chunk. This makes it easier to
+  deal with alignments etc but can be very confusing when trying
+  to extend or adapt this code.
+
+  The exceptions to all this are
+
+     1. The special chunk `top' is the top-most available chunk (i.e.,
+        the one bordering the end of available memory). It is treated
+        specially.  Top is never included in any bin, is used only if
+        no other chunk is available, and is released back to the
+        system if it is very large (see M_TRIM_THRESHOLD).  In effect,
+        the top chunk is treated as larger (and thus less well
+        fitting) than any other available chunk.  The top chunk
+        doesn't update its trailing size field since there is no next
+        contiguous chunk that would have to index off it. However,
+        space is still allocated for it (TOP_FOOT_SIZE) to enable
+        separation or merging when space is extended.
+
+     3. Chunks allocated via mmap, have both cinuse and pinuse bits
+        cleared in their head fields.  Because they are allocated
+        one-by-one, each must carry its own prev_foot field, which is
+        also used to hold the offset this chunk has within its mmapped
+        region, which is needed to preserve alignment. Each mmapped
+        chunk is trailed by the first two fields of a fake next-chunk
+        for sake of usage checks.
+
+*/
+
+struct malloc_chunk {
+  size_t               prev_foot;  /* Size of previous chunk (if free).  */
+  size_t               head;       /* Size and inuse bits. */
+  struct malloc_chunk* fd;         /* double links -- used only if free. */
+  struct malloc_chunk* bk;
+};
+
+typedef struct malloc_chunk  mchunk;
+typedef struct malloc_chunk* mchunkptr;
+typedef struct malloc_chunk* sbinptr;  /* The type of bins of chunks */
+typedef unsigned int bindex_t;         /* Described below */
+typedef unsigned int binmap_t;         /* Described below */
+typedef unsigned int flag_t;           /* The type of various bit flag sets */
+
+/* ------------------- Chunks sizes and alignments ----------------------- */
+
+#define MCHUNK_SIZE         (sizeof(mchunk))
+
+#if FOOTERS
+#define CHUNK_OVERHEAD      (TWO_SIZE_T_SIZES)
+#else /* FOOTERS */
+#define CHUNK_OVERHEAD      (SIZE_T_SIZE)
+#endif /* FOOTERS */
+
+/* MMapped chunks need a second word of overhead ... */
+#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES)
+/* ... and additional padding for fake next-chunk at foot */
+#define MMAP_FOOT_PAD       (FOUR_SIZE_T_SIZES)
+
+/* The smallest size we can malloc is an aligned minimal chunk */
+#define MIN_CHUNK_SIZE\
+  ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
+
+/* conversion from malloc headers to user pointers, and back */
+#define chunk2mem(p)        ((void*)((char*)(p)       + TWO_SIZE_T_SIZES))
+#define mem2chunk(mem)      ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES))
+/* chunk associated with aligned address A */
+#define align_as_chunk(A)   (mchunkptr)((A) + align_offset(chunk2mem(A)))
+
+/* Bounds on request (not chunk) sizes. */
+#define MAX_REQUEST         ((-MIN_CHUNK_SIZE) << 2)
+#define MIN_REQUEST         (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE)
+
+/* pad request bytes into a usable size */
+#define pad_request(req) \
+   (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)
+
+/* pad request, checking for minimum (but not maximum) */
+#define request2size(req) \
+  (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req))
+
+
+/* ------------------ Operations on head and foot fields ----------------- */
+
+/*
+  The head field of a chunk is or'ed with PINUSE_BIT when previous
+  adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in
+  use, unless mmapped, in which case both bits are cleared.
+
+  FLAG4_BIT is not used by this malloc, but might be useful in extensions.
+*/
+
+#define PINUSE_BIT          (SIZE_T_ONE)
+#define CINUSE_BIT          (SIZE_T_TWO)
+#define FLAG4_BIT           (SIZE_T_FOUR)
+#define INUSE_BITS          (PINUSE_BIT|CINUSE_BIT)
+#define FLAG_BITS           (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT)
+
+/* Head value for fenceposts */
+#define FENCEPOST_HEAD      (INUSE_BITS|SIZE_T_SIZE)
+
+/* extraction of fields from head words */
+#define cinuse(p)           ((p)->head & CINUSE_BIT)
+#define pinuse(p)           ((p)->head & PINUSE_BIT)
+#define flag4inuse(p)       ((p)->head & FLAG4_BIT)
+#define is_inuse(p)         (((p)->head & INUSE_BITS) != PINUSE_BIT)
+#define is_mmapped(p)       (((p)->head & INUSE_BITS) == 0)
+
+#define chunksize(p)        ((p)->head & ~(FLAG_BITS))
+
+#define clear_pinuse(p)     ((p)->head &= ~PINUSE_BIT)
+#define set_flag4(p)        ((p)->head |= FLAG4_BIT)
+#define clear_flag4(p)      ((p)->head &= ~FLAG4_BIT)
+
+/* Treat space at ptr +/- offset as a chunk */
+#define chunk_plus_offset(p, s)  ((mchunkptr)(((char*)(p)) + (s)))
+#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s)))
+
+/* Ptr to next or previous physical malloc_chunk. */
+#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS)))
+#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) ))
+
+/* extract next chunk's pinuse bit */
+#define next_pinuse(p)  ((next_chunk(p)->head) & PINUSE_BIT)
+
+/* Get/set size at footer */
+#define get_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot)
+#define set_foot(p, s)  (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s))
+
+/* Set size, pinuse bit, and foot */
+#define set_size_and_pinuse_of_free_chunk(p, s)\
+  ((p)->head = (s|PINUSE_BIT), set_foot(p, s))
+
+/* Set size, pinuse bit, foot, and clear next pinuse */
+#define set_free_with_pinuse(p, s, n)\
+  (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s))
+
+/* Get the internal overhead associated with chunk p */
+#define overhead_for(p)\
+ (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD)
+
+/* Return true if malloced space is not necessarily cleared */
+#if MMAP_CLEARS
+#define calloc_must_clear(p) (!is_mmapped(p))
+#else /* MMAP_CLEARS */
+#define calloc_must_clear(p) (1)
+#endif /* MMAP_CLEARS */
+
+/* ---------------------- Overlaid data structures ----------------------- */
+
+/*
+  When chunks are not in use, they are treated as nodes of either
+  lists or trees.
+
+  "Small"  chunks are stored in circular doubly-linked lists, and look
+  like this:
+
+    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Size of previous chunk                            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `head:' |             Size of chunk, in bytes                         |P|
+      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Forward pointer to next chunk in list             |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Back pointer to previous chunk in list            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Unused space (may be 0 bytes long)                .
+            .                                                               .
+            .                                                               |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `foot:' |             Size of chunk, in bytes                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  Larger chunks are kept in a form of bitwise digital trees (aka
+  tries) keyed on chunksizes.  Because malloc_tree_chunks are only for
+  free chunks greater than 256 bytes, their size doesn't impose any
+  constraints on user chunk sizes.  Each node looks like:
+
+    chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Size of previous chunk                            |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `head:' |             Size of chunk, in bytes                         |P|
+      mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Forward pointer to next chunk of same size        |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Back pointer to previous chunk of same size       |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to left child (child[0])                  |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to right child (child[1])                 |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Pointer to parent                                 |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             bin index of this chunk                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+            |             Unused space                                      .
+            .                                                               |
+nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+    `foot:' |             Size of chunk, in bytes                           |
+            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+  Each tree holding treenodes is a tree of unique chunk sizes.  Chunks
+  of the same size are arranged in a circularly-linked list, with only
+  the oldest chunk (the next to be used, in our FIFO ordering)
+  actually in the tree.  (Tree members are distinguished by a non-null
+  parent pointer.)  If a chunk with the same size an an existing node
+  is inserted, it is linked off the existing node using pointers that
+  work in the same way as fd/bk pointers of small chunks.
+
+  Each tree contains a power of 2 sized range of chunk sizes (the
+  smallest is 0x100 <= x < 0x180), which is is divided in half at each
+  tree level, with the chunks in the smaller half of the range (0x100
+  <= x < 0x140 for the top nose) in the left subtree and the larger
+  half (0x140 <= x < 0x180) in the right subtree.  This is, of course,
+  done by inspecting individual bits.
+
+  Using these rules, each node's left subtree contains all smaller
+  sizes than its right subtree.  However, the node at the root of each
+  subtree has no particular ordering relationship to either.  (The
+  dividing line between the subtree sizes is based on trie relation.)
+  If we remove the last chunk of a given size from the interior of the
+  tree, we need to replace it with a leaf node.  The tree ordering
+  rules permit a node to be replaced by any leaf below it.
+
+  The smallest chunk in a tree (a common operation in a best-fit
+  allocator) can be found by walking a path to the leftmost leaf in
+  the tree.  Unlike a usual binary tree, where we follow left child
+  pointers until we reach a null, here we follow the right child
+  pointer any time the left one is null, until we reach a leaf with
+  both child pointers null. The smallest chunk in the tree will be
+  somewhere along that path.
+
+  The worst case number of steps to add, find, or remove a node is
+  bounded by the number of bits differentiating chunks within
+  bins. Under current bin calculations, this ranges from 6 up to 21
+  (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case
+  is of course much better.
+*/
+
+struct malloc_tree_chunk {
+  /* The first four fields must be compatible with malloc_chunk */
+  size_t                    prev_foot;
+  size_t                    head;
+  struct malloc_tree_chunk* fd;
+  struct malloc_tree_chunk* bk;
+
+  struct malloc_tree_chunk* child[2];
+  struct malloc_tree_chunk* parent;
+  bindex_t                  index;
+};
+
+typedef struct malloc_tree_chunk  tchunk;
+typedef struct malloc_tree_chunk* tchunkptr;
+typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */
+
+/* A little helper macro for trees */
+#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1])
+
+/* ----------------------------- Segments -------------------------------- */
+
+/*
+  Each malloc space may include non-contiguous segments, held in a
+  list headed by an embedded malloc_segment record representing the
+  top-most space. Segments also include flags holding properties of
+  the space. Large chunks that are directly allocated by mmap are not
+  included in this list. They are instead independently created and
+  destroyed without otherwise keeping track of them.
+
+  Segment management mainly comes into play for spaces allocated by
+  MMAP.  Any call to MMAP might or might not return memory that is
+  adjacent to an existing segment.  MORECORE normally contiguously
+  extends the current space, so this space is almost always adjacent,
+  which is simpler and faster to deal with. (This is why MORECORE is
+  used preferentially to MMAP when both are available -- see
+  sys_alloc.)  When allocating using MMAP, we don't use any of the
+  hinting mechanisms (inconsistently) supported in various
+  implementations of unix mmap, or distinguish reserving from
+  committing memory. Instead, we just ask for space, and exploit
+  contiguity when we get it.  It is probably possible to do
+  better than this on some systems, but no general scheme seems
+  to be significantly better.
+
+  Management entails a simpler variant of the consolidation scheme
+  used for chunks to reduce fragmentation -- new adjacent memory is
+  normally prepended or appended to an existing segment. However,
+  there are limitations compared to chunk consolidation that mostly
+  reflect the fact that segment processing is relatively infrequent
+  (occurring only when getting memory from system) and that we
+  don't expect to have huge numbers of segments:
+
+  * Segments are not indexed, so traversal requires linear scans.  (It
+    would be possible to index these, but is not worth the extra
+    overhead and complexity for most programs on most platforms.)
+  * New segments are only appended to old ones when holding top-most
+    memory; if they cannot be prepended to others, they are held in
+    different segments.
+
+  Except for the top-most segment of an mstate, each segment record
+  is kept at the tail of its segment. Segments are added by pushing
+  segment records onto the list headed by &mstate.seg for the
+  containing mstate.
+
+  Segment flags control allocation/merge/deallocation policies:
+  * If EXTERN_BIT set, then we did not allocate this segment,
+    and so should not try to deallocate or merge with others.
+    (This currently holds only for the initial segment passed
+    into create_mspace_with_base.)
+  * If USE_MMAP_BIT set, the segment may be merged with
+    other surrounding mmapped segments and trimmed/de-allocated
+    using munmap.
+  * If neither bit is set, then the segment was obtained using
+    MORECORE so can be merged with surrounding MORECORE'd segments
+    and deallocated/trimmed using MORECORE with negative arguments.
+*/
+
+struct malloc_segment {
+  char*        base;             /* base address */
+  size_t       size;             /* allocated size */
+  struct malloc_segment* next;   /* ptr to next segment */
+  flag_t       sflags;           /* mmap and extern flag */
+};
+
+#define is_mmapped_segment(S)  ((S)->sflags & USE_MMAP_BIT)
+#define is_extern_segment(S)   ((S)->sflags & EXTERN_BIT)
+
+typedef struct malloc_segment  msegment;
+typedef struct malloc_segment* msegmentptr;
+
+/* ---------------------------- malloc_state ----------------------------- */
+
+/*
+   A malloc_state holds all of the bookkeeping for a space.
+   The main fields are:
+
+  Top
+    The topmost chunk of the currently active segment. Its size is
+    cached in topsize.  The actual size of topmost space is
+    topsize+TOP_FOOT_SIZE, which includes space reserved for adding
+    fenceposts and segment records if necessary when getting more
+    space from the system.  The size at which to autotrim top is
+    cached from mparams in trim_check, except that it is disabled if
+    an autotrim fails.
+
+  Designated victim (dv)
+    This is the preferred chunk for servicing small requests that
+    don't have exact fits.  It is normally the chunk split off most
+    recently to service another small request.  Its size is cached in
+    dvsize. The link fields of this chunk are not maintained since it
+    is not kept in a bin.
+
+  SmallBins
+    An array of bin headers for free chunks.  These bins hold chunks
+    with sizes less than MIN_LARGE_SIZE bytes. Each bin contains
+    chunks of all the same size, spaced 8 bytes apart.  To simplify
+    use in double-linked lists, each bin header acts as a malloc_chunk
+    pointing to the real first node, if it exists (else pointing to
+    itself).  This avoids special-casing for headers.  But to avoid
+    waste, we allocate only the fd/bk pointers of bins, and then use
+    repositioning tricks to treat these as the fields of a chunk.
+
+  TreeBins
+    Treebins are pointers to the roots of trees holding a range of
+    sizes. There are 2 equally spaced treebins for each power of two
+    from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything
+    larger.
+
+  Bin maps
+    There is one bit map for small bins ("smallmap") and one for
+    treebins ("treemap).  Each bin sets its bit when non-empty, and
+    clears the bit when empty.  Bit operations are then used to avoid
+    bin-by-bin searching -- nearly all "search" is done without ever
+    looking at bins that won't be selected.  The bit maps
+    conservatively use 32 bits per map word, even if on 64bit system.
+    For a good description of some of the bit-based techniques used
+    here, see Henry S. Warren Jr's book "Hacker's Delight" (and
+    supplement at http://hackersdelight.org/). Many of these are
+    intended to reduce the branchiness of paths through malloc etc, as
+    well as to reduce the number of memory locations read or written.
+
+  Segments
+    A list of segments headed by an embedded malloc_segment record
+    representing the initial space.
+
+  Address check support
+    The least_addr field is the least address ever obtained from
+    MORECORE or MMAP. Attempted frees and reallocs of any address less
+    than this are trapped (unless INSECURE is defined).
+
+  Magic tag
+    A cross-check field that should always hold same value as mparams.magic.
+
+  Max allowed footprint
+    The maximum allowed bytes to allocate from system (zero means no limit)
+
+  Flags
+    Bits recording whether to use MMAP, locks, or contiguous MORECORE
+
+  Statistics
+    Each space keeps track of current and maximum system memory
+    obtained via MORECORE or MMAP.
+
+  Trim support
+    Fields holding the amount of unused topmost memory that should trigger
+    trimming, and a counter to force periodic scanning to release unused
+    non-topmost segments.
+
+  Locking
+    If USE_LOCKS is defined, the "mutex" lock is acquired and released
+    around every public call using this mspace.
+
+  Extension support
+    A void* pointer and a size_t field that can be used to help implement
+    extensions to this malloc.
+*/
+
+/* Bin types, widths and sizes */
+#define NSMALLBINS        (32U)
+#define NTREEBINS         (32U)
+#define SMALLBIN_SHIFT    (3U)
+#define SMALLBIN_WIDTH    (SIZE_T_ONE << SMALLBIN_SHIFT)
+#define TREEBIN_SHIFT     (8U)
+#define MIN_LARGE_SIZE    (SIZE_T_ONE << TREEBIN_SHIFT)
+#define MAX_SMALL_SIZE    (MIN_LARGE_SIZE - SIZE_T_ONE)
+#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD)
+
+struct malloc_state {
+  binmap_t   smallmap;
+  binmap_t   treemap;
+  size_t     dvsize;
+  size_t     topsize;
+  char*      least_addr;
+  mchunkptr  dv;
+  mchunkptr  top;
+  size_t     trim_check;
+  size_t     release_checks;
+  size_t     magic;
+  mchunkptr  smallbins[(NSMALLBINS+1)*2];
+  tbinptr    treebins[NTREEBINS];
+  size_t     footprint;
+  size_t     max_footprint;
+  size_t     footprint_limit; /* zero means no limit */
+  flag_t     mflags;
+#if USE_LOCKS
+  MLOCK_T    mutex;     /* locate lock among fields that rarely change */
+#endif /* USE_LOCKS */
+  msegment   seg;
+  void*      extp;      /* Unused but available for extensions */
+  size_t     exts;
+};
+
+typedef struct malloc_state*    mstate;
+
+/* ------------- Global malloc_state and malloc_params ------------------- */
+
+/*
+  malloc_params holds global properties, including those that can be
+  dynamically set using mallopt. There is a single instance, mparams,
+  initialized in init_mparams. Note that the non-zeroness of "magic"
+  also serves as an initialization flag.
+*/
+
+struct malloc_params {
+  size_t magic;
+  size_t page_size;
+  size_t granularity;
+  size_t mmap_threshold;
+  size_t trim_threshold;
+  flag_t default_mflags;
+};
+
+static struct malloc_params mparams;
+
+/* Ensure mparams initialized */
+#define ensure_initialization() (void)(mparams.magic != 0 || init_mparams())
+
+#if !ONLY_MSPACES
+
+/* The global malloc_state used for all non-"mspace" calls */
+static struct malloc_state _gm_;
+#define gm                 (&_gm_)
+#define is_global(M)       ((M) == &_gm_)
+
+#endif /* !ONLY_MSPACES */
+
+#define is_initialized(M)  ((M)->top != 0)
+
+/* -------------------------- system alloc setup ------------------------- */
+
+/* Operations on mflags */
+
+#define use_lock(M)           ((M)->mflags &   USE_LOCK_BIT)
+#define enable_lock(M)        ((M)->mflags |=  USE_LOCK_BIT)
+#if USE_LOCKS
+#define disable_lock(M)       ((M)->mflags &= ~USE_LOCK_BIT)
+#else
+#define disable_lock(M)
+#endif
+
+#define use_mmap(M)           ((M)->mflags &   USE_MMAP_BIT)
+#define enable_mmap(M)        ((M)->mflags |=  USE_MMAP_BIT)
+#if HAVE_MMAP
+#define disable_mmap(M)       ((M)->mflags &= ~USE_MMAP_BIT)
+#else
+#define disable_mmap(M)
+#endif
+
+#define use_noncontiguous(M)  ((M)->mflags &   USE_NONCONTIGUOUS_BIT)
+#define disable_contiguous(M) ((M)->mflags |=  USE_NONCONTIGUOUS_BIT)
+
+#define set_lock(M,L)\
+ ((M)->mflags = (L)?\
+  ((M)->mflags | USE_LOCK_BIT) :\
+  ((M)->mflags & ~USE_LOCK_BIT))
+
+/* page-align a size */
+#define page_align(S)\
+ (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE))
+
+/* granularity-align a size */
+#define granularity_align(S)\
+  (((S) + (mparams.granularity - SIZE_T_ONE))\
+   & ~(mparams.granularity - SIZE_T_ONE))
+
+
+/* For mmap, use granularity alignment on windows, else page-align */
+#ifdef WIN32
+#define mmap_align(S) granularity_align(S)
+#else
+#define mmap_align(S) page_align(S)
+#endif
+
+/* For sys_alloc, enough padding to ensure can malloc request on success */
+#define SYS_ALLOC_PADDING (TOP_FOOT_SIZE + MALLOC_ALIGNMENT)
+
+#define is_page_aligned(S)\
+   (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0)
+#define is_granularity_aligned(S)\
+   (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0)
+
+/*  True if segment S holds address A */
+#define segment_holds(S, A)\
+  ((char*)(A) >= S->base && (char*)(A) < S->base + S->size)
+
+/* Return segment holding given address */
+static msegmentptr segment_holding(mstate m, char* addr) {
+  msegmentptr sp = &m->seg;
+  for (;;) {
+    if (addr >= sp->base && addr < sp->base + sp->size)
+      return sp;
+    if ((sp = sp->next) == 0)
+      return 0;
+  }
+}
+
+/* Return true if segment contains a segment link */
+static int has_segment_link(mstate m, msegmentptr ss) {
+  msegmentptr sp = &m->seg;
+  for (;;) {
+    if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size)
+      return 1;
+    if ((sp = sp->next) == 0)
+      return 0;
+  }
+}
+
+#ifndef MORECORE_CANNOT_TRIM
+#define should_trim(M,s)  ((s) > (M)->trim_check)
+#else  /* MORECORE_CANNOT_TRIM */
+#define should_trim(M,s)  (0)
+#endif /* MORECORE_CANNOT_TRIM */
+
+/*
+  TOP_FOOT_SIZE is padding at the end of a segment, including space
+  that may be needed to place segment records and fenceposts when new
+  noncontiguous segments are added.
+*/
+#define TOP_FOOT_SIZE\
+  (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE)
+
+
+/* -------------------------------  Hooks -------------------------------- */
+
+/*
+  PREACTION should be defined to return 0 on success, and nonzero on
+  failure. If you are not using locking, you can redefine these to do
+  anything you like.
+*/
+
+#if USE_LOCKS
+#define PREACTION(M)  ((use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0)
+#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); }
+#else /* USE_LOCKS */
+
+#ifndef PREACTION
+#define PREACTION(M) (0)
+#endif  /* PREACTION */
+
+#ifndef POSTACTION
+#define POSTACTION(M)
+#endif  /* POSTACTION */
+
+#endif /* USE_LOCKS */
+
+/*
+  CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses.
+  USAGE_ERROR_ACTION is triggered on detected bad frees and
+  reallocs. The argument p is an address that might have triggered the
+  fault. It is ignored by the two predefined actions, but might be
+  useful in custom actions that try to help diagnose errors.
+*/
+
+#if PROCEED_ON_ERROR
+
+/* A count of the number of corruption errors causing resets */
+int malloc_corruption_error_count;
+
+/* default corruption action */
+static void reset_on_error(mstate m);
+
+#define CORRUPTION_ERROR_ACTION(m)  reset_on_error(m)
+#define USAGE_ERROR_ACTION(m, p)
+
+#else /* PROCEED_ON_ERROR */
+
+#ifndef CORRUPTION_ERROR_ACTION
+#define CORRUPTION_ERROR_ACTION(m) ABORT
+#endif /* CORRUPTION_ERROR_ACTION */
+
+#ifndef USAGE_ERROR_ACTION
+#define USAGE_ERROR_ACTION(m,p) ABORT
+#endif /* USAGE_ERROR_ACTION */
+
+#endif /* PROCEED_ON_ERROR */
+
+
+/* -------------------------- Debugging setup ---------------------------- */
+
+#if ! DEBUG
+
+#define check_free_chunk(M,P)
+#define check_inuse_chunk(M,P)
+#define check_malloced_chunk(M,P,N)
+#define check_mmapped_chunk(M,P)
+#define check_malloc_state(M)
+#define check_top_chunk(M,P)
+
+#else /* DEBUG */
+#define check_free_chunk(M,P)       do_check_free_chunk(M,P)
+#define check_inuse_chunk(M,P)      do_check_inuse_chunk(M,P)
+#define check_top_chunk(M,P)        do_check_top_chunk(M,P)
+#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N)
+#define check_mmapped_chunk(M,P)    do_check_mmapped_chunk(M,P)
+#define check_malloc_state(M)       do_check_malloc_state(M)
+
+static void   do_check_any_chunk(mstate m, mchunkptr p);
+static void   do_check_top_chunk(mstate m, mchunkptr p);
+static void   do_check_mmapped_chunk(mstate m, mchunkptr p);
+static void   do_check_inuse_chunk(mstate m, mchunkptr p);
+static void   do_check_free_chunk(mstate m, mchunkptr p);
+static void   do_check_malloced_chunk(mstate m, void* mem, size_t s);
+static void   do_check_tree(mstate m, tchunkptr t);
+static void   do_check_treebin(mstate m, bindex_t i);
+static void   do_check_smallbin(mstate m, bindex_t i);
+static void   do_check_malloc_state(mstate m);
+static int    bin_find(mstate m, mchunkptr x);
+static size_t traverse_and_check(mstate m);
+#endif /* DEBUG */
+
+/* ---------------------------- Indexing Bins ---------------------------- */
+
+#define is_small(s)         (((s) >> SMALLBIN_SHIFT) < NSMALLBINS)
+#define small_index(s)      (bindex_t)((s)  >> SMALLBIN_SHIFT)
+#define small_index2size(i) ((i)  << SMALLBIN_SHIFT)
+#define MIN_SMALL_INDEX     (small_index(MIN_CHUNK_SIZE))
+
+/* addressing by index. See above about smallbin repositioning */
+#define smallbin_at(M, i)   ((sbinptr)((char*)&((M)->smallbins[(i)<<1])))
+#define treebin_at(M,i)     (&((M)->treebins[i]))
+
+/* assign tree index for size S to variable I. Use x86 asm if possible  */
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+#define compute_tree_index(S, I)\
+{\
+  unsigned int X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int K = (unsigned) sizeof(X)*__CHAR_BIT__ - 1 - (unsigned) __builtin_clz(X); \
+    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
+  }\
+}
+
+#elif defined (__INTEL_COMPILER)
+#define compute_tree_index(S, I)\
+{\
+  size_t X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int K = _bit_scan_reverse (X); \
+    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
+  }\
+}
+
+#elif defined(_MSC_VER) && _MSC_VER>=1300
+#define compute_tree_index(S, I)\
+{\
+  size_t X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int K;\
+    _BitScanReverse((DWORD *) &K, (DWORD) X);\
+    I =  (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\
+  }\
+}
+
+#else /* GNUC */
+#define compute_tree_index(S, I)\
+{\
+  size_t X = S >> TREEBIN_SHIFT;\
+  if (X == 0)\
+    I = 0;\
+  else if (X > 0xFFFF)\
+    I = NTREEBINS-1;\
+  else {\
+    unsigned int Y = (unsigned int)X;\
+    unsigned int N = ((Y - 0x100) >> 16) & 8;\
+    unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\
+    N += K;\
+    N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\
+    K = 14 - N + ((Y <<= K) >> 15);\
+    I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\
+  }\
+}
+#endif /* GNUC */
+
+/* Bit representing maximum resolved size in a treebin at i */
+#define bit_for_tree_index(i) \
+   (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2)
+
+/* Shift placing maximum resolved bit in a treebin at i as sign bit */
+#define leftshift_for_tree_index(i) \
+   ((i == NTREEBINS-1)? 0 : \
+    ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2)))
+
+/* The size of the smallest chunk held in bin with index i */
+#define minsize_for_tree_index(i) \
+   ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) |  \
+   (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1)))
+
+
+/* ------------------------ Operations on bin maps ----------------------- */
+
+/* bit corresponding to given index */
+#define idx2bit(i)              ((binmap_t)(1) << (i))
+
+/* Mark/Clear bits with given index */
+#define mark_smallmap(M,i)      ((M)->smallmap |=  idx2bit(i))
+#define clear_smallmap(M,i)     ((M)->smallmap &= ~idx2bit(i))
+#define smallmap_is_marked(M,i) ((M)->smallmap &   idx2bit(i))
+
+#define mark_treemap(M,i)       ((M)->treemap  |=  idx2bit(i))
+#define clear_treemap(M,i)      ((M)->treemap  &= ~idx2bit(i))
+#define treemap_is_marked(M,i)  ((M)->treemap  &   idx2bit(i))
+
+/* isolate the least set bit of a bitmap */
+#define least_bit(x)         ((x) & -(x))
+
+/* mask with all bits to left of least bit of x on */
+#define left_bits(x)         ((x<<1) | -(x<<1))
+
+/* mask with all bits to left of or equal to least bit of x on */
+#define same_or_left_bits(x) ((x) | -(x))
+
+/* index corresponding to given bit. Use x86 asm if possible */
+
+#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int J;\
+  J = __builtin_ctz(X); \
+  I = (bindex_t)J;\
+}
+
+#elif defined (__INTEL_COMPILER)
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int J;\
+  J = _bit_scan_forward (X); \
+  I = (bindex_t)J;\
+}
+
+#elif defined(_MSC_VER) && _MSC_VER>=1300
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int J;\
+  _BitScanForward((DWORD *) &J, X);\
+  I = (bindex_t)J;\
+}
+
+#elif USE_BUILTIN_FFS
+#define compute_bit2idx(X, I) I = ffs(X)-1
+
+#else
+#define compute_bit2idx(X, I)\
+{\
+  unsigned int Y = X - 1;\
+  unsigned int K = Y >> (16-4) & 16;\
+  unsigned int N = K;        Y >>= K;\
+  N += K = Y >> (8-3) &  8;  Y >>= K;\
+  N += K = Y >> (4-2) &  4;  Y >>= K;\
+  N += K = Y >> (2-1) &  2;  Y >>= K;\
+  N += K = Y >> (1-0) &  1;  Y >>= K;\
+  I = (bindex_t)(N + Y);\
+}
+#endif /* GNUC */
+
+
+/* ----------------------- Runtime Check Support ------------------------- */
+
+/*
+  For security, the main invariant is that malloc/free/etc never
+  writes to a static address other than malloc_state, unless static
+  malloc_state itself has been corrupted, which cannot occur via
+  malloc (because of these checks). In essence this means that we
+  believe all pointers, sizes, maps etc held in malloc_state, but
+  check all of those linked or offsetted from other embedded data
+  structures.  These checks are interspersed with main code in a way
+  that tends to minimize their run-time cost.
+
+  When FOOTERS is defined, in addition to range checking, we also
+  verify footer fields of inuse chunks, which can be used guarantee
+  that the mstate controlling malloc/free is intact.  This is a
+  streamlined version of the approach described by William Robertson
+  et al in "Run-time Detection of Heap-based Overflows" LISA'03
+  http://www.usenix.org/events/lisa03/tech/robertson.html The footer
+  of an inuse chunk holds the xor of its mstate and a random seed,
+  that is checked upon calls to free() and realloc().  This is
+  (probabalistically) unguessable from outside the program, but can be
+  computed by any code successfully malloc'ing any chunk, so does not
+  itself provide protection against code that has already broken
+  security through some other means.  Unlike Robertson et al, we
+  always dynamically check addresses of all offset chunks (previous,
+  next, etc). This turns out to be cheaper than relying on hashes.
+*/
+
+#if !INSECURE
+/* Check if address a is at least as high as any from MORECORE or MMAP */
+#define ok_address(M, a) ((char*)(a) >= (M)->least_addr)
+/* Check if address of next chunk n is higher than base chunk p */
+#define ok_next(p, n)    ((char*)(p) < (char*)(n))
+/* Check if p has inuse status */
+#define ok_inuse(p)     is_inuse(p)
+/* Check if p has its pinuse bit on */
+#define ok_pinuse(p)     pinuse(p)
+
+#else /* !INSECURE */
+#define ok_address(M, a) (1)
+#define ok_next(b, n)    (1)
+#define ok_inuse(p)      (1)
+#define ok_pinuse(p)     (1)
+#endif /* !INSECURE */
+
+#if (FOOTERS && !INSECURE)
+/* Check if (alleged) mstate m has expected magic field */
+#define ok_magic(M)      ((M)->magic == mparams.magic)
+#else  /* (FOOTERS && !INSECURE) */
+#define ok_magic(M)      (1)
+#endif /* (FOOTERS && !INSECURE) */
+
+/* In gcc, use __builtin_expect to minimize impact of checks */
+#if !INSECURE
+#if defined(__GNUC__) && __GNUC__ >= 3
+#define RTCHECK(e)  __builtin_expect(e, 1)
+#else /* GNUC */
+#define RTCHECK(e)  (e)
+#endif /* GNUC */
+#else /* !INSECURE */
+#define RTCHECK(e)  (1)
+#endif /* !INSECURE */
+
+/* macros to set up inuse chunks with or without footers */
+
+#if !FOOTERS
+
+#define mark_inuse_foot(M,p,s)
+
+/* Macros for setting head/foot of non-mmapped chunks */
+
+/* Set cinuse bit and pinuse bit of next chunk */
+#define set_inuse(M,p,s)\
+  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
+  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
+
+/* Set cinuse and pinuse of this chunk and pinuse of next chunk */
+#define set_inuse_and_pinuse(M,p,s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT)
+
+/* Set size, cinuse and pinuse bit of this chunk */
+#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT))
+
+#else /* FOOTERS */
+
+/* Set foot of inuse chunk to be xor of mstate and seed */
+#define mark_inuse_foot(M,p,s)\
+  (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic))
+
+#define get_mstate_for(p)\
+  ((mstate)(((mchunkptr)((char*)(p) +\
+    (chunksize(p))))->prev_foot ^ mparams.magic))
+
+#define set_inuse(M,p,s)\
+  ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\
+  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \
+  mark_inuse_foot(M,p,s))
+
+#define set_inuse_and_pinuse(M,p,s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\
+ mark_inuse_foot(M,p,s))
+
+#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\
+  ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\
+  mark_inuse_foot(M, p, s))
+
+#endif /* !FOOTERS */
+
+/* ---------------------------- setting mparams -------------------------- */
+
+#if LOCK_AT_FORK
+static void pre_fork(void)         { ACQUIRE_LOCK(&(gm)->mutex); }
+static void post_fork_parent(void) { RELEASE_LOCK(&(gm)->mutex); }
+static void post_fork_child(void)  { INITIAL_LOCK(&(gm)->mutex); }
+#endif /* LOCK_AT_FORK */
+
+/* Initialize mparams */
+static int init_mparams(void) {
+#ifdef NEED_GLOBAL_LOCK_INIT
+  if (malloc_global_mutex_status <= 0)
+    init_malloc_global_mutex();
+#endif
+
+  ACQUIRE_MALLOC_GLOBAL_LOCK();
+  if (mparams.magic == 0) {
+    size_t magic;
+    size_t psize;
+    size_t gsize;
+
+#ifndef WIN32
+    psize = malloc_getpagesize;
+    gsize = ((DEFAULT_GRANULARITY != 0)? DEFAULT_GRANULARITY : psize);
+#else /* WIN32 */
+    {
+      SYSTEM_INFO system_info;
+      GetSystemInfo(&system_info);
+      psize = system_info.dwPageSize;
+      gsize = ((DEFAULT_GRANULARITY != 0)?
+               DEFAULT_GRANULARITY : system_info.dwAllocationGranularity);
+    }
+#endif /* WIN32 */
+
+    /* Sanity-check configuration:
+       size_t must be unsigned and as wide as pointer type.
+       ints must be at least 4 bytes.
+       alignment must be at least 8.
+       Alignment, min chunk size, and page size must all be powers of 2.
+    */
+    if ((sizeof(size_t) != sizeof(char*)) ||
+        (MAX_SIZE_T < MIN_CHUNK_SIZE)  ||
+        (sizeof(int) < 4)  ||
+        (MALLOC_ALIGNMENT < (size_t)8U) ||
+        ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) ||
+        ((MCHUNK_SIZE      & (MCHUNK_SIZE-SIZE_T_ONE))      != 0) ||
+        ((gsize            & (gsize-SIZE_T_ONE))            != 0) ||
+        ((psize            & (psize-SIZE_T_ONE))            != 0))
+      ABORT;
+    mparams.granularity = gsize;
+    mparams.page_size = psize;
+    mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
+    mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD;
+#if MORECORE_CONTIGUOUS
+    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT;
+#else  /* MORECORE_CONTIGUOUS */
+    mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT;
+#endif /* MORECORE_CONTIGUOUS */
+
+#if !ONLY_MSPACES
+    /* Set up lock for main malloc area */
+    gm->mflags = mparams.default_mflags;
+    (void)INITIAL_LOCK(&gm->mutex);
+#endif
+#if LOCK_AT_FORK
+    pthread_atfork(&pre_fork, &post_fork_parent, &post_fork_child);
+#endif
+
+    {
+#if USE_DEV_RANDOM
+      int fd;
+      unsigned char buf[sizeof(size_t)];
+      /* Try to use /dev/urandom, else fall back on using time */
+      if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 &&
+          read(fd, buf, sizeof(buf)) == sizeof(buf)) {
+        magic = *((size_t *) buf);
+        close(fd);
+      }
+      else
+#endif /* USE_DEV_RANDOM */
+#ifdef WIN32
+      magic = (size_t)(GetTickCount() ^ (size_t)0x55555555U);
+#elif defined(LACKS_TIME_H)
+      magic = (size_t)&magic ^ (size_t)0x55555555U;
+#else
+      magic = (size_t)(time(0) ^ (size_t)0x55555555U);
+#endif
+      magic |= (size_t)8U;    /* ensure nonzero */
+      magic &= ~(size_t)7U;   /* improve chances of fault for bad values */
+      /* Until memory modes commonly available, use volatile-write */
+      (*(volatile size_t *)(&(mparams.magic))) = magic;
+    }
+  }
+
+  RELEASE_MALLOC_GLOBAL_LOCK();
+  return 1;
+}
+
+/* support for mallopt */
+static int change_mparam(int param_number, int value) {
+  size_t val;
+  ensure_initialization();
+  val = (value == -1)? MAX_SIZE_T : (size_t)value;
+  switch(param_number) {
+  case M_TRIM_THRESHOLD:
+    mparams.trim_threshold = val;
+    return 1;
+  case M_GRANULARITY:
+    if (val >= mparams.page_size && ((val & (val-1)) == 0)) {
+      mparams.granularity = val;
+      return 1;
+    }
+    else
+      return 0;
+  case M_MMAP_THRESHOLD:
+    mparams.mmap_threshold = val;
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+#if DEBUG
+/* ------------------------- Debugging Support --------------------------- */
+
+/* Check properties of any chunk, whether free, inuse, mmapped etc  */
+static void do_check_any_chunk(mstate m, mchunkptr p) {
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+}
+
+/* Check properties of top chunk */
+static void do_check_top_chunk(mstate m, mchunkptr p) {
+  msegmentptr sp = segment_holding(m, (char*)p);
+  size_t  sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */
+  assert(sp != 0);
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+  assert(sz == m->topsize);
+  assert(sz > 0);
+  assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE);
+  assert(pinuse(p));
+  assert(!pinuse(chunk_plus_offset(p, sz)));
+}
+
+/* Check properties of (inuse) mmapped chunks */
+static void do_check_mmapped_chunk(mstate m, mchunkptr p) {
+  size_t  sz = chunksize(p);
+  size_t len = (sz + (p->prev_foot) + MMAP_FOOT_PAD);
+  assert(is_mmapped(p));
+  assert(use_mmap(m));
+  assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD));
+  assert(ok_address(m, p));
+  assert(!is_small(sz));
+  assert((len & (mparams.page_size-SIZE_T_ONE)) == 0);
+  assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD);
+  assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0);
+}
+
+/* Check properties of inuse chunks */
+static void do_check_inuse_chunk(mstate m, mchunkptr p) {
+  do_check_any_chunk(m, p);
+  assert(is_inuse(p));
+  assert(next_pinuse(p));
+  /* If not pinuse and not mmapped, previous chunk has OK offset */
+  assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p);
+  if (is_mmapped(p))
+    do_check_mmapped_chunk(m, p);
+}
+
+/* Check properties of free chunks */
+static void do_check_free_chunk(mstate m, mchunkptr p) {
+  size_t sz = chunksize(p);
+  mchunkptr next = chunk_plus_offset(p, sz);
+  do_check_any_chunk(m, p);
+  assert(!is_inuse(p));
+  assert(!next_pinuse(p));
+  assert (!is_mmapped(p));
+  if (p != m->dv && p != m->top) {
+    if (sz >= MIN_CHUNK_SIZE) {
+      assert((sz & CHUNK_ALIGN_MASK) == 0);
+      assert(is_aligned(chunk2mem(p)));
+      assert(next->prev_foot == sz);
+      assert(pinuse(p));
+      assert (next == m->top || is_inuse(next));
+      assert(p->fd->bk == p);
+      assert(p->bk->fd == p);
+    }
+    else  /* markers are always of size SIZE_T_SIZE */
+      assert(sz == SIZE_T_SIZE);
+  }
+}
+
+/* Check properties of malloced chunks at the point they are malloced */
+static void do_check_malloced_chunk(mstate m, void* mem, size_t s) {
+  if (mem != 0) {
+    mchunkptr p = mem2chunk(mem);
+    size_t sz = p->head & ~INUSE_BITS;
+    do_check_inuse_chunk(m, p);
+    assert((sz & CHUNK_ALIGN_MASK) == 0);
+    assert(sz >= MIN_CHUNK_SIZE);
+    assert(sz >= s);
+    /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */
+    assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE));
+  }
+}
+
+/* Check a tree and its subtrees.  */
+static void do_check_tree(mstate m, tchunkptr t) {
+  tchunkptr head = 0;
+  tchunkptr u = t;
+  bindex_t tindex = t->index;
+  size_t tsize = chunksize(t);
+  bindex_t idx;
+  compute_tree_index(tsize, idx);
+  assert(tindex == idx);
+  assert(tsize >= MIN_LARGE_SIZE);
+  assert(tsize >= minsize_for_tree_index(idx));
+  assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1))));
+
+  do { /* traverse through chain of same-sized nodes */
+    do_check_any_chunk(m, ((mchunkptr)u));
+    assert(u->index == tindex);
+    assert(chunksize(u) == tsize);
+    assert(!is_inuse(u));
+    assert(!next_pinuse(u));
+    assert(u->fd->bk == u);
+    assert(u->bk->fd == u);
+    if (u->parent == 0) {
+      assert(u->child[0] == 0);
+      assert(u->child[1] == 0);
+    }
+    else {
+      assert(head == 0); /* only one node on chain has parent */
+      head = u;
+      assert(u->parent != u);
+      assert (u->parent->child[0] == u ||
+              u->parent->child[1] == u ||
+              *((tbinptr*)(u->parent)) == u);
+      if (u->child[0] != 0) {
+        assert(u->child[0]->parent == u);
+        assert(u->child[0] != u);
+        do_check_tree(m, u->child[0]);
+      }
+      if (u->child[1] != 0) {
+        assert(u->child[1]->parent == u);
+        assert(u->child[1] != u);
+        do_check_tree(m, u->child[1]);
+      }
+      if (u->child[0] != 0 && u->child[1] != 0) {
+        assert(chunksize(u->child[0]) < chunksize(u->child[1]));
+      }
+    }
+    u = u->fd;
+  } while (u != t);
+  assert(head != 0);
+}
+
+/*  Check all the chunks in a treebin.  */
+static void do_check_treebin(mstate m, bindex_t i) {
+  tbinptr* tb = treebin_at(m, i);
+  tchunkptr t = *tb;
+  int empty = (m->treemap & (1U << i)) == 0;
+  if (t == 0)
+    assert(empty);
+  if (!empty)
+    do_check_tree(m, t);
+}
+
+/*  Check all the chunks in a smallbin.  */
+static void do_check_smallbin(mstate m, bindex_t i) {
+  sbinptr b = smallbin_at(m, i);
+  mchunkptr p = b->bk;
+  unsigned int empty = (m->smallmap & (1U << i)) == 0;
+  if (p == b)
+    assert(empty);
+  if (!empty) {
+    for (; p != b; p = p->bk) {
+      size_t size = chunksize(p);
+      mchunkptr q;
+      /* each chunk claims to be free */
+      do_check_free_chunk(m, p);
+      /* chunk belongs in bin */
+      assert(small_index(size) == i);
+      assert(p->bk == b || chunksize(p->bk) == chunksize(p));
+      /* chunk is followed by an inuse chunk */
+      q = next_chunk(p);
+      if (q->head != FENCEPOST_HEAD)
+        do_check_inuse_chunk(m, q);
+    }
+  }
+}
+
+/* Find x in a bin. Used in other check functions. */
+static int bin_find(mstate m, mchunkptr x) {
+  size_t size = chunksize(x);
+  if (is_small(size)) {
+    bindex_t sidx = small_index(size);
+    sbinptr b = smallbin_at(m, sidx);
+    if (smallmap_is_marked(m, sidx)) {
+      mchunkptr p = b;
+      do {
+        if (p == x)
+          return 1;
+      } while ((p = p->fd) != b);
+    }
+  }
+  else {
+    bindex_t tidx;
+    compute_tree_index(size, tidx);
+    if (treemap_is_marked(m, tidx)) {
+      tchunkptr t = *treebin_at(m, tidx);
+      size_t sizebits = size << leftshift_for_tree_index(tidx);
+      while (t != 0 && chunksize(t) != size) {
+        t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
+        sizebits <<= 1;
+      }
+      if (t != 0) {
+        tchunkptr u = t;
+        do {
+          if (u == (tchunkptr)x)
+            return 1;
+        } while ((u = u->fd) != t);
+      }
+    }
+  }
+  return 0;
+}
+
+/* Traverse each chunk and check it; return total */
+static size_t traverse_and_check(mstate m) {
+  size_t sum = 0;
+  if (is_initialized(m)) {
+    msegmentptr s = &m->seg;
+    sum += m->topsize + TOP_FOOT_SIZE;
+    while (s != 0) {
+      mchunkptr q = align_as_chunk(s->base);
+      mchunkptr lastq = 0;
+      assert(pinuse(q));
+      while (segment_holds(s, q) &&
+             q != m->top && q->head != FENCEPOST_HEAD) {
+        sum += chunksize(q);
+        if (is_inuse(q)) {
+          assert(!bin_find(m, q));
+          do_check_inuse_chunk(m, q);
+        }
+        else {
+          assert(q == m->dv || bin_find(m, q));
+          assert(lastq == 0 || is_inuse(lastq)); /* Not 2 consecutive free */
+          do_check_free_chunk(m, q);
+        }
+        lastq = q;
+        q = next_chunk(q);
+      }
+      s = s->next;
+    }
+  }
+  return sum;
+}
+
+
+/* Check all properties of malloc_state. */
+static void do_check_malloc_state(mstate m) {
+  bindex_t i;
+  size_t total;
+  /* check bins */
+  for (i = 0; i < NSMALLBINS; ++i)
+    do_check_smallbin(m, i);
+  for (i = 0; i < NTREEBINS; ++i)
+    do_check_treebin(m, i);
+
+  if (m->dvsize != 0) { /* check dv chunk */
+    do_check_any_chunk(m, m->dv);
+    assert(m->dvsize == chunksize(m->dv));
+    assert(m->dvsize >= MIN_CHUNK_SIZE);
+    assert(bin_find(m, m->dv) == 0);
+  }
+
+  if (m->top != 0) {   /* check top chunk */
+    do_check_top_chunk(m, m->top);
+    /*assert(m->topsize == chunksize(m->top)); redundant */
+    assert(m->topsize > 0);
+    assert(bin_find(m, m->top) == 0);
+  }
+
+  total = traverse_and_check(m);
+  assert(total <= m->footprint);
+  assert(m->footprint <= m->max_footprint);
+}
+#endif /* DEBUG */
+
+/* ----------------------------- statistics ------------------------------ */
+
+#if !NO_MALLINFO
+static struct mallinfo internal_mallinfo(mstate m) {
+  struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+  ensure_initialization();
+  if (!PREACTION(m)) {
+    check_malloc_state(m);
+    if (is_initialized(m)) {
+      size_t nfree = SIZE_T_ONE; /* top always free */
+      size_t mfree = m->topsize + TOP_FOOT_SIZE;
+      size_t sum = mfree;
+      msegmentptr s = &m->seg;
+      while (s != 0) {
+        mchunkptr q = align_as_chunk(s->base);
+        while (segment_holds(s, q) &&
+               q != m->top && q->head != FENCEPOST_HEAD) {
+          size_t sz = chunksize(q);
+          sum += sz;
+          if (!is_inuse(q)) {
+            mfree += sz;
+            ++nfree;
+          }
+          q = next_chunk(q);
+        }
+        s = s->next;
+      }
+
+      nm.arena    = sum;
+      nm.ordblks  = nfree;
+      nm.hblkhd   = m->footprint - sum;
+      nm.usmblks  = m->max_footprint;
+      nm.uordblks = m->footprint - mfree;
+      nm.fordblks = mfree;
+      nm.keepcost = m->topsize;
+    }
+
+    POSTACTION(m);
+  }
+  return nm;
+}
+#endif /* !NO_MALLINFO */
+
+#if !NO_MALLOC_STATS
+static void internal_malloc_stats(mstate m) {
+  ensure_initialization();
+  if (!PREACTION(m)) {
+    size_t maxfp = 0;
+    size_t fp = 0;
+    size_t used = 0;
+    check_malloc_state(m);
+    if (is_initialized(m)) {
+      msegmentptr s = &m->seg;
+      maxfp = m->max_footprint;
+      fp = m->footprint;
+      used = fp - (m->topsize + TOP_FOOT_SIZE);
+
+      while (s != 0) {
+        mchunkptr q = align_as_chunk(s->base);
+        while (segment_holds(s, q) &&
+               q != m->top && q->head != FENCEPOST_HEAD) {
+          if (!is_inuse(q))
+            used -= chunksize(q);
+          q = next_chunk(q);
+        }
+        s = s->next;
+      }
+    }
+    POSTACTION(m); /* drop lock */
+    fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp));
+    fprintf(stderr, "system bytes     = %10lu\n", (unsigned long)(fp));
+    fprintf(stderr, "in use bytes     = %10lu\n", (unsigned long)(used));
+  }
+}
+#endif /* NO_MALLOC_STATS */
+
+/* ----------------------- Operations on smallbins ----------------------- */
+
+/*
+  Various forms of linking and unlinking are defined as macros.  Even
+  the ones for trees, which are very long but have very short typical
+  paths.  This is ugly but reduces reliance on inlining support of
+  compilers.
+*/
+
+/* Link a free chunk into a smallbin  */
+#define insert_small_chunk(M, P, S) {\
+  bindex_t I  = small_index(S);\
+  mchunkptr B = smallbin_at(M, I);\
+  mchunkptr F = B;\
+  assert(S >= MIN_CHUNK_SIZE);\
+  if (!smallmap_is_marked(M, I))\
+    mark_smallmap(M, I);\
+  else if (RTCHECK(ok_address(M, B->fd)))\
+    F = B->fd;\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+  B->fd = P;\
+  F->bk = P;\
+  P->fd = F;\
+  P->bk = B;\
+}
+
+/* Unlink a chunk from a smallbin  */
+#define unlink_small_chunk(M, P, S) {\
+  mchunkptr F = P->fd;\
+  mchunkptr B = P->bk;\
+  bindex_t I = small_index(S);\
+  assert(P != B);\
+  assert(P != F);\
+  assert(chunksize(P) == small_index2size(I));\
+  if (RTCHECK(F == smallbin_at(M,I) || (ok_address(M, F) && F->bk == P))) { \
+    if (B == F) {\
+      clear_smallmap(M, I);\
+    }\
+    else if (RTCHECK(B == smallbin_at(M,I) ||\
+                     (ok_address(M, B) && B->fd == P))) {\
+      F->bk = B;\
+      B->fd = F;\
+    }\
+    else {\
+      CORRUPTION_ERROR_ACTION(M);\
+    }\
+  }\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+}
+
+/* Unlink the first chunk from a smallbin */
+#define unlink_first_small_chunk(M, B, P, I) {\
+  mchunkptr F = P->fd;\
+  assert(P != B);\
+  assert(P != F);\
+  assert(chunksize(P) == small_index2size(I));\
+  if (B == F) {\
+    clear_smallmap(M, I);\
+  }\
+  else if (RTCHECK(ok_address(M, F) && F->bk == P)) {\
+    F->bk = B;\
+    B->fd = F;\
+  }\
+  else {\
+    CORRUPTION_ERROR_ACTION(M);\
+  }\
+}
+
+/* Replace dv node, binning the old one */
+/* Used only when dvsize known to be small */
+#define replace_dv(M, P, S) {\
+  size_t DVS = M->dvsize;\
+  assert(is_small(DVS));\
+  if (DVS != 0) {\
+    mchunkptr DV = M->dv;\
+    insert_small_chunk(M, DV, DVS);\
+  }\
+  M->dvsize = S;\
+  M->dv = P;\
+}
+
+/* ------------------------- Operations on trees ------------------------- */
+
+/* Insert chunk into tree */
+#define insert_large_chunk(M, X, S) {\
+  tbinptr* H;\
+  bindex_t I;\
+  compute_tree_index(S, I);\
+  H = treebin_at(M, I);\
+  X->index = I;\
+  X->child[0] = X->child[1] = 0;\
+  if (!treemap_is_marked(M, I)) {\
+    mark_treemap(M, I);\
+    *H = X;\
+    X->parent = (tchunkptr)H;\
+    X->fd = X->bk = X;\
+  }\
+  else {\
+    tchunkptr T = *H;\
+    size_t K = S << leftshift_for_tree_index(I);\
+    for (;;) {\
+      if (chunksize(T) != S) {\
+        tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\
+        K <<= 1;\
+        if (*C != 0)\
+          T = *C;\
+        else if (RTCHECK(ok_address(M, C))) {\
+          *C = X;\
+          X->parent = T;\
+          X->fd = X->bk = X;\
+          break;\
+        }\
+        else {\
+          CORRUPTION_ERROR_ACTION(M);\
+          break;\
+        }\
+      }\
+      else {\
+        tchunkptr F = T->fd;\
+        if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\
+          T->fd = F->bk = X;\
+          X->fd = F;\
+          X->bk = T;\
+          X->parent = 0;\
+          break;\
+        }\
+        else {\
+          CORRUPTION_ERROR_ACTION(M);\
+          break;\
+        }\
+      }\
+    }\
+  }\
+}
+
+/*
+  Unlink steps:
+
+  1. If x is a chained node, unlink it from its same-sized fd/bk links
+     and choose its bk node as its replacement.
+  2. If x was the last node of its size, but not a leaf node, it must
+     be replaced with a leaf node (not merely one with an open left or
+     right), to make sure that lefts and rights of descendents
+     correspond properly to bit masks.  We use the rightmost descendent
+     of x.  We could use any other leaf, but this is easy to locate and
+     tends to counteract removal of leftmosts elsewhere, and so keeps
+     paths shorter than minimally guaranteed.  This doesn't loop much
+     because on average a node in a tree is near the bottom.
+  3. If x is the base of a chain (i.e., has parent links) relink
+     x's parent and children to x's replacement (or null if none).
+*/
+
+#define unlink_large_chunk(M, X) {\
+  tchunkptr XP = X->parent;\
+  tchunkptr R;\
+  if (X->bk != X) {\
+    tchunkptr F = X->fd;\
+    R = X->bk;\
+    if (RTCHECK(ok_address(M, F) && F->bk == X && R->fd == X)) {\
+      F->bk = R;\
+      R->fd = F;\
+    }\
+    else {\
+      CORRUPTION_ERROR_ACTION(M);\
+    }\
+  }\
+  else {\
+    tchunkptr* RP;\
+    if (((R = *(RP = &(X->child[1]))) != 0) ||\
+        ((R = *(RP = &(X->child[0]))) != 0)) {\
+      tchunkptr* CP;\
+      while ((*(CP = &(R->child[1])) != 0) ||\
+             (*(CP = &(R->child[0])) != 0)) {\
+        R = *(RP = CP);\
+      }\
+      if (RTCHECK(ok_address(M, RP)))\
+        *RP = 0;\
+      else {\
+        CORRUPTION_ERROR_ACTION(M);\
+      }\
+    }\
+  }\
+  if (XP != 0) {\
+    tbinptr* H = treebin_at(M, X->index);\
+    if (X == *H) {\
+      if ((*H = R) == 0) \
+        clear_treemap(M, X->index);\
+    }\
+    else if (RTCHECK(ok_address(M, XP))) {\
+      if (XP->child[0] == X) \
+        XP->child[0] = R;\
+      else \
+        XP->child[1] = R;\
+    }\
+    else\
+      CORRUPTION_ERROR_ACTION(M);\
+    if (R != 0) {\
+      if (RTCHECK(ok_address(M, R))) {\
+        tchunkptr C0, C1;\
+        R->parent = XP;\
+        if ((C0 = X->child[0]) != 0) {\
+          if (RTCHECK(ok_address(M, C0))) {\
+            R->child[0] = C0;\
+            C0->parent = R;\
+          }\
+          else\
+            CORRUPTION_ERROR_ACTION(M);\
+        }\
+        if ((C1 = X->child[1]) != 0) {\
+          if (RTCHECK(ok_address(M, C1))) {\
+            R->child[1] = C1;\
+            C1->parent = R;\
+          }\
+          else\
+            CORRUPTION_ERROR_ACTION(M);\
+        }\
+      }\
+      else\
+        CORRUPTION_ERROR_ACTION(M);\
+    }\
+  }\
+}
+
+/* Relays to large vs small bin operations */
+
+#define insert_chunk(M, P, S)\
+  if (is_small(S)) insert_small_chunk(M, P, S)\
+  else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); }
+
+#define unlink_chunk(M, P, S)\
+  if (is_small(S)) unlink_small_chunk(M, P, S)\
+  else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); }
+
+
+/* Relays to internal calls to malloc/free from realloc, memalign etc */
+
+#if ONLY_MSPACES
+#define internal_malloc(m, b) mspace_malloc(m, b)
+#define internal_free(m, mem) mspace_free(m,mem);
+#else /* ONLY_MSPACES */
+#if MSPACES
+#define internal_malloc(m, b)\
+  ((m == gm)? dlmalloc(b) : mspace_malloc(m, b))
+#define internal_free(m, mem)\
+   if (m == gm) dlfree(mem); else mspace_free(m,mem);
+#else /* MSPACES */
+#define internal_malloc(m, b) dlmalloc(b)
+#define internal_free(m, mem) dlfree(mem)
+#endif /* MSPACES */
+#endif /* ONLY_MSPACES */
+
+/* -----------------------  Direct-mmapping chunks ----------------------- */
+
+/*
+  Directly mmapped chunks are set up with an offset to the start of
+  the mmapped region stored in the prev_foot field of the chunk. This
+  allows reconstruction of the required argument to MUNMAP when freed,
+  and also allows adjustment of the returned chunk to meet alignment
+  requirements (especially in memalign).
+*/
+
+/* Malloc using mmap */
+static void* mmap_alloc(mstate m, size_t nb) {
+  size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
+  if (m->footprint_limit != 0) {
+    size_t fp = m->footprint + mmsize;
+    if (fp <= m->footprint || fp > m->footprint_limit)
+      return 0;
+  }
+  if (mmsize > nb) {     /* Check for wrap around 0 */
+    char* mm = (char*)(CALL_DIRECT_MMAP(mmsize));
+    if (mm != CMFAIL) {
+      size_t offset = align_offset(chunk2mem(mm));
+      size_t psize = mmsize - offset - MMAP_FOOT_PAD;
+      mchunkptr p = (mchunkptr)(mm + offset);
+      p->prev_foot = offset;
+      p->head = psize;
+      mark_inuse_foot(m, p, psize);
+      chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD;
+      chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0;
+
+      if (m->least_addr == 0 || mm < m->least_addr)
+        m->least_addr = mm;
+      if ((m->footprint += mmsize) > m->max_footprint)
+        m->max_footprint = m->footprint;
+      assert(is_aligned(chunk2mem(p)));
+      check_mmapped_chunk(m, p);
+      return chunk2mem(p);
+    }
+  }
+  return 0;
+}
+
+/* Realloc using mmap */
+static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb, int flags) {
+  size_t oldsize = chunksize(oldp);
+  (void)flags; /* placate people compiling -Wunused */
+  if (is_small(nb)) /* Can't shrink mmap regions below small size */
+    return 0;
+  /* Keep old chunk if big enough but not too big */
+  if (oldsize >= nb + SIZE_T_SIZE &&
+      (oldsize - nb) <= (mparams.granularity << 1))
+    return oldp;
+  else {
+    size_t offset = oldp->prev_foot;
+    size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD;
+    size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
+    char* cp = (char*)CALL_MREMAP((char*)oldp - offset,
+                                  oldmmsize, newmmsize, flags);
+    if (cp != CMFAIL) {
+      mchunkptr newp = (mchunkptr)(cp + offset);
+      size_t psize = newmmsize - offset - MMAP_FOOT_PAD;
+      newp->head = psize;
+      mark_inuse_foot(m, newp, psize);
+      chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD;
+      chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0;
+
+      if (cp < m->least_addr)
+        m->least_addr = cp;
+      if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint)
+        m->max_footprint = m->footprint;
+      check_mmapped_chunk(m, newp);
+      return newp;
+    }
+  }
+  return 0;
+}
+
+
+/* -------------------------- mspace management -------------------------- */
+
+/* Initialize top chunk and its size */
+static void init_top(mstate m, mchunkptr p, size_t psize) {
+  /* Ensure alignment */
+  size_t offset = align_offset(chunk2mem(p));
+  p = (mchunkptr)((char*)p + offset);
+  psize -= offset;
+
+  m->top = p;
+  m->topsize = psize;
+  p->head = psize | PINUSE_BIT;
+  /* set size of fake trailing chunk holding overhead space only once */
+  chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE;
+  m->trim_check = mparams.trim_threshold; /* reset on each update */
+}
+
+/* Initialize bins for a new mstate that is otherwise zeroed out */
+static void init_bins(mstate m) {
+  /* Establish circular links for smallbins */
+  bindex_t i;
+  for (i = 0; i < NSMALLBINS; ++i) {
+    sbinptr bin = smallbin_at(m,i);
+    bin->fd = bin->bk = bin;
+  }
+}
+
+#if PROCEED_ON_ERROR
+
+/* default corruption action */
+static void reset_on_error(mstate m) {
+  int i;
+  ++malloc_corruption_error_count;
+  /* Reinitialize fields to forget about all memory */
+  m->smallmap = m->treemap = 0;
+  m->dvsize = m->topsize = 0;
+  m->seg.base = 0;
+  m->seg.size = 0;
+  m->seg.next = 0;
+  m->top = m->dv = 0;
+  for (i = 0; i < NTREEBINS; ++i)
+    *treebin_at(m, i) = 0;
+  init_bins(m);
+}
+#endif /* PROCEED_ON_ERROR */
+
+/* Allocate chunk and prepend remainder with chunk in successor base. */
+static void* prepend_alloc(mstate m, char* newbase, char* oldbase,
+                           size_t nb) {
+  mchunkptr p = align_as_chunk(newbase);
+  mchunkptr oldfirst = align_as_chunk(oldbase);
+  size_t psize = (char*)oldfirst - (char*)p;
+  mchunkptr q = chunk_plus_offset(p, nb);
+  size_t qsize = psize - nb;
+  set_size_and_pinuse_of_inuse_chunk(m, p, nb);
+
+  assert((char*)oldfirst > (char*)q);
+  assert(pinuse(oldfirst));
+  assert(qsize >= MIN_CHUNK_SIZE);
+
+  /* consolidate remainder with first chunk of old base */
+  if (oldfirst == m->top) {
+    size_t tsize = m->topsize += qsize;
+    m->top = q;
+    q->head = tsize | PINUSE_BIT;
+    check_top_chunk(m, q);
+  }
+  else if (oldfirst == m->dv) {
+    size_t dsize = m->dvsize += qsize;
+    m->dv = q;
+    set_size_and_pinuse_of_free_chunk(q, dsize);
+  }
+  else {
+    if (!is_inuse(oldfirst)) {
+      size_t nsize = chunksize(oldfirst);
+      unlink_chunk(m, oldfirst, nsize);
+      oldfirst = chunk_plus_offset(oldfirst, nsize);
+      qsize += nsize;
+    }
+    set_free_with_pinuse(q, qsize, oldfirst);
+    insert_chunk(m, q, qsize);
+    check_free_chunk(m, q);
+  }
+
+  check_malloced_chunk(m, chunk2mem(p), nb);
+  return chunk2mem(p);
+}
+
+/* Add a segment to hold a new noncontiguous region */
+static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) {
+  /* Determine locations and sizes of segment, fenceposts, old top */
+  char* old_top = (char*)m->top;
+  msegmentptr oldsp = segment_holding(m, old_top);
+  char* old_end = oldsp->base + oldsp->size;
+  size_t ssize = pad_request(sizeof(struct malloc_segment));
+  char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK);
+  size_t offset = align_offset(chunk2mem(rawsp));
+  char* asp = rawsp + offset;
+  char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp;
+  mchunkptr sp = (mchunkptr)csp;
+  msegmentptr ss = (msegmentptr)(chunk2mem(sp));
+  mchunkptr tnext = chunk_plus_offset(sp, ssize);
+  mchunkptr p = tnext;
+  int nfences = 0;
+
+  /* reset top to new space */
+  init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
+
+  /* Set up segment record */
+  assert(is_aligned(ss));
+  set_size_and_pinuse_of_inuse_chunk(m, sp, ssize);
+  *ss = m->seg; /* Push current record */
+  m->seg.base = tbase;
+  m->seg.size = tsize;
+  m->seg.sflags = mmapped;
+  m->seg.next = ss;
+
+  /* Insert trailing fenceposts */
+  for (;;) {
+    mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE);
+    p->head = FENCEPOST_HEAD;
+    ++nfences;
+    if ((char*)(&(nextp->head)) < old_end)
+      p = nextp;
+    else
+      break;
+  }
+  assert(nfences >= 2);
+
+  /* Insert the rest of old top into a bin as an ordinary free chunk */
+  if (csp != old_top) {
+    mchunkptr q = (mchunkptr)old_top;
+    size_t psize = csp - old_top;
+    mchunkptr tn = chunk_plus_offset(q, psize);
+    set_free_with_pinuse(q, psize, tn);
+    insert_chunk(m, q, psize);
+  }
+
+  check_top_chunk(m, m->top);
+}
+
+/* -------------------------- System allocation -------------------------- */
+
+/* Get memory from system using MORECORE or MMAP */
+static void* sys_alloc(mstate m, size_t nb) {
+  char* tbase = CMFAIL;
+  size_t tsize = 0;
+  flag_t mmap_flag = 0;
+  size_t asize; /* allocation size */
+
+  ensure_initialization();
+
+  /* Directly map large chunks, but only if already initialized */
+  if (use_mmap(m) && nb >= mparams.mmap_threshold && m->topsize != 0) {
+    void* mem = mmap_alloc(m, nb);
+    if (mem != 0)
+      return mem;
+  }
+
+  asize = granularity_align(nb + SYS_ALLOC_PADDING);
+  if (asize <= nb)
+    return 0; /* wraparound */
+  if (m->footprint_limit != 0) {
+    size_t fp = m->footprint + asize;
+    if (fp <= m->footprint || fp > m->footprint_limit)
+      return 0;
+  }
+
+  /*
+    Try getting memory in any of three ways (in most-preferred to
+    least-preferred order):
+    1. A call to MORECORE that can normally contiguously extend memory.
+       (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or
+       or main space is mmapped or a previous contiguous call failed)
+    2. A call to MMAP new space (disabled if not HAVE_MMAP).
+       Note that under the default settings, if MORECORE is unable to
+       fulfill a request, and HAVE_MMAP is true, then mmap is
+       used as a noncontiguous system allocator. This is a useful backup
+       strategy for systems with holes in address spaces -- in this case
+       sbrk cannot contiguously expand the heap, but mmap may be able to
+       find space.
+    3. A call to MORECORE that cannot usually contiguously extend memory.
+       (disabled if not HAVE_MORECORE)
+
+   In all cases, we need to request enough bytes from system to ensure
+   we can malloc nb bytes upon success, so pad with enough space for
+   top_foot, plus alignment-pad to make sure we don't lose bytes if
+   not on boundary, and round this up to a granularity unit.
+  */
+
+  if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) {
+    char* br = CMFAIL;
+    size_t ssize = asize; /* sbrk call size */
+    msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top);
+    ACQUIRE_MALLOC_GLOBAL_LOCK();
+
+    if (ss == 0) {  /* First time through or recovery */
+      char* base = (char*)CALL_MORECORE(0);
+      if (base != CMFAIL) {
+        size_t fp;
+        /* Adjust to end on a page boundary */
+        if (!is_page_aligned(base))
+          ssize += (page_align((size_t)base) - (size_t)base);
+        fp = m->footprint + ssize; /* recheck limits */
+        if (ssize > nb && ssize < HALF_MAX_SIZE_T &&
+            (m->footprint_limit == 0 ||
+             (fp > m->footprint && fp <= m->footprint_limit)) &&
+            (br = (char*)(CALL_MORECORE(ssize))) == base) {
+          tbase = base;
+          tsize = ssize;
+        }
+      }
+    }
+    else {
+      /* Subtract out existing available top space from MORECORE request. */
+      ssize = granularity_align(nb - m->topsize + SYS_ALLOC_PADDING);
+      /* Use mem here only if it did continuously extend old space */
+      if (ssize < HALF_MAX_SIZE_T &&
+          (br = (char*)(CALL_MORECORE(ssize))) == ss->base+ss->size) {
+        tbase = br;
+        tsize = ssize;
+      }
+    }
+
+    if (tbase == CMFAIL) {    /* Cope with partial failure */
+      if (br != CMFAIL) {    /* Try to use/extend the space we did get */
+        if (ssize < HALF_MAX_SIZE_T &&
+            ssize < nb + SYS_ALLOC_PADDING) {
+          size_t esize = granularity_align(nb + SYS_ALLOC_PADDING - ssize);
+          if (esize < HALF_MAX_SIZE_T) {
+            char* end = (char*)CALL_MORECORE(esize);
+            if (end != CMFAIL)
+              ssize += esize;
+            else {            /* Can't use; try to release */
+              (void) CALL_MORECORE(-ssize);
+              br = CMFAIL;
+            }
+          }
+        }
+      }
+      if (br != CMFAIL) {    /* Use the space we did get */
+        tbase = br;
+        tsize = ssize;
+      }
+      else
+        disable_contiguous(m); /* Don't try contiguous path in the future */
+    }
+
+    RELEASE_MALLOC_GLOBAL_LOCK();
+  }
+
+  if (HAVE_MMAP && tbase == CMFAIL) {  /* Try MMAP */
+    char* mp = (char*)(CALL_MMAP(asize));
+    if (mp != CMFAIL) {
+      tbase = mp;
+      tsize = asize;
+      mmap_flag = USE_MMAP_BIT;
+    }
+  }
+
+  if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */
+    if (asize < HALF_MAX_SIZE_T) {
+      char* br = CMFAIL;
+      char* end = CMFAIL;
+      ACQUIRE_MALLOC_GLOBAL_LOCK();
+      br = (char*)(CALL_MORECORE(asize));
+      end = (char*)(CALL_MORECORE(0));
+      RELEASE_MALLOC_GLOBAL_LOCK();
+      if (br != CMFAIL && end != CMFAIL && br < end) {
+        size_t ssize = end - br;
+        if (ssize > nb + TOP_FOOT_SIZE) {
+          tbase = br;
+          tsize = ssize;
+        }
+      }
+    }
+  }
+
+  if (tbase != CMFAIL) {
+
+    if ((m->footprint += tsize) > m->max_footprint)
+      m->max_footprint = m->footprint;
+
+    if (!is_initialized(m)) { /* first-time initialization */
+      if (m->least_addr == 0 || tbase < m->least_addr)
+        m->least_addr = tbase;
+      m->seg.base = tbase;
+      m->seg.size = tsize;
+      m->seg.sflags = mmap_flag;
+      m->magic = mparams.magic;
+      m->release_checks = MAX_RELEASE_CHECK_RATE;
+      init_bins(m);
+#if !ONLY_MSPACES
+      if (is_global(m))
+        init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE);
+      else
+#endif
+      {
+        /* Offset top by embedded malloc_state */
+        mchunkptr mn = next_chunk(mem2chunk(m));
+        init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE);
+      }
+    }
+
+    else {
+      /* Try to merge with an existing segment */
+      msegmentptr sp = &m->seg;
+      /* Only consider most recent segment if traversal suppressed */
+      while (sp != 0 && tbase != sp->base + sp->size)
+        sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
+      if (sp != 0 &&
+          !is_extern_segment(sp) &&
+          (sp->sflags & USE_MMAP_BIT) == mmap_flag &&
+          segment_holds(sp, m->top)) { /* append */
+        sp->size += tsize;
+        init_top(m, m->top, m->topsize + tsize);
+      }
+      else {
+        if (tbase < m->least_addr)
+          m->least_addr = tbase;
+        sp = &m->seg;
+        while (sp != 0 && sp->base != tbase + tsize)
+          sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next;
+        if (sp != 0 &&
+            !is_extern_segment(sp) &&
+            (sp->sflags & USE_MMAP_BIT) == mmap_flag) {
+          char* oldbase = sp->base;
+          sp->base = tbase;
+          sp->size += tsize;
+          return prepend_alloc(m, tbase, oldbase, nb);
+        }
+        else
+          add_segment(m, tbase, tsize, mmap_flag);
+      }
+    }
+
+    if (nb < m->topsize) { /* Allocate from new or extended top space */
+      size_t rsize = m->topsize -= nb;
+      mchunkptr p = m->top;
+      mchunkptr r = m->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(m, p, nb);
+      check_top_chunk(m, m->top);
+      check_malloced_chunk(m, chunk2mem(p), nb);
+      return chunk2mem(p);
+    }
+  }
+
+  MALLOC_FAILURE_ACTION;
+  return 0;
+}
+
+/* -----------------------  system deallocation -------------------------- */
+
+/* Unmap and unlink any mmapped segments that don't contain used chunks */
+static size_t release_unused_segments(mstate m) {
+  size_t released = 0;
+  int nsegs = 0;
+  msegmentptr pred = &m->seg;
+  msegmentptr sp = pred->next;
+  while (sp != 0) {
+    char* base = sp->base;
+    size_t size = sp->size;
+    msegmentptr next = sp->next;
+    ++nsegs;
+    if (is_mmapped_segment(sp) && !is_extern_segment(sp)) {
+      mchunkptr p = align_as_chunk(base);
+      size_t psize = chunksize(p);
+      /* Can unmap if first chunk holds entire segment and not pinned */
+      if (!is_inuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) {
+        tchunkptr tp = (tchunkptr)p;
+        assert(segment_holds(sp, (char*)sp));
+        if (p == m->dv) {
+          m->dv = 0;
+          m->dvsize = 0;
+        }
+        else {
+          unlink_large_chunk(m, tp);
+        }
+        if (CALL_MUNMAP(base, size) == 0) {
+          released += size;
+          m->footprint -= size;
+          /* unlink obsoleted record */
+          sp = pred;
+          sp->next = next;
+        }
+        else { /* back out if cannot unmap */
+          insert_large_chunk(m, tp, psize);
+        }
+      }
+    }
+    if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */
+      break;
+    pred = sp;
+    sp = next;
+  }
+  /* Reset check counter */
+  m->release_checks = (((size_t) nsegs > (size_t) MAX_RELEASE_CHECK_RATE)?
+                       (size_t) nsegs : (size_t) MAX_RELEASE_CHECK_RATE);
+  return released;
+}
+
+static int sys_trim(mstate m, size_t pad) {
+  size_t released = 0;
+  ensure_initialization();
+  if (pad < MAX_REQUEST && is_initialized(m)) {
+    pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */
+
+    if (m->topsize > pad) {
+      /* Shrink top space in granularity-size units, keeping at least one */
+      size_t unit = mparams.granularity;
+      size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit -
+                      SIZE_T_ONE) * unit;
+      msegmentptr sp = segment_holding(m, (char*)m->top);
+
+      if (!is_extern_segment(sp)) {
+        if (is_mmapped_segment(sp)) {
+          if (HAVE_MMAP &&
+              sp->size >= extra &&
+              !has_segment_link(m, sp)) { /* can't shrink if pinned */
+            size_t newsize = sp->size - extra;
+            (void)newsize; /* placate people compiling -Wunused-variable */
+            /* Prefer mremap, fall back to munmap */
+            if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
+                (CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
+              released = extra;
+            }
+          }
+        }
+        else if (HAVE_MORECORE) {
+          if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */
+            extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit;
+          ACQUIRE_MALLOC_GLOBAL_LOCK();
+          {
+            /* Make sure end of memory is where we last set it. */
+            char* old_br = (char*)(CALL_MORECORE(0));
+            if (old_br == sp->base + sp->size) {
+              char* rel_br = (char*)(CALL_MORECORE(-extra));
+              char* new_br = (char*)(CALL_MORECORE(0));
+              if (rel_br != CMFAIL && new_br < old_br)
+                released = old_br - new_br;
+            }
+          }
+          RELEASE_MALLOC_GLOBAL_LOCK();
+        }
+      }
+
+      if (released != 0) {
+        sp->size -= released;
+        m->footprint -= released;
+        init_top(m, m->top, m->topsize - released);
+        check_top_chunk(m, m->top);
+      }
+    }
+
+    /* Unmap any unused mmapped segments */
+    if (HAVE_MMAP)
+      released += release_unused_segments(m);
+
+    /* On failure, disable autotrim to avoid repeated failed future calls */
+    if (released == 0 && m->topsize > m->trim_check)
+      m->trim_check = MAX_SIZE_T;
+  }
+
+  return (released != 0)? 1 : 0;
+}
+
+/* Consolidate and bin a chunk. Differs from exported versions
+   of free mainly in that the chunk need not be marked as inuse.
+*/
+static void dispose_chunk(mstate m, mchunkptr p, size_t psize) {
+  mchunkptr next = chunk_plus_offset(p, psize);
+  if (!pinuse(p)) {
+    mchunkptr prev;
+    size_t prevsize = p->prev_foot;
+    if (is_mmapped(p)) {
+      psize += prevsize + MMAP_FOOT_PAD;
+      if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
+        m->footprint -= psize;
+      return;
+    }
+    prev = chunk_minus_offset(p, prevsize);
+    psize += prevsize;
+    p = prev;
+    if (RTCHECK(ok_address(m, prev))) { /* consolidate backward */
+      if (p != m->dv) {
+        unlink_chunk(m, p, prevsize);
+      }
+      else if ((next->head & INUSE_BITS) == INUSE_BITS) {
+        m->dvsize = psize;
+        set_free_with_pinuse(p, psize, next);
+        return;
+      }
+    }
+    else {
+      CORRUPTION_ERROR_ACTION(m);
+      return;
+    }
+  }
+  if (RTCHECK(ok_address(m, next))) {
+    if (!cinuse(next)) {  /* consolidate forward */
+      if (next == m->top) {
+        size_t tsize = m->topsize += psize;
+        m->top = p;
+        p->head = tsize | PINUSE_BIT;
+        if (p == m->dv) {
+          m->dv = 0;
+          m->dvsize = 0;
+        }
+        return;
+      }
+      else if (next == m->dv) {
+        size_t dsize = m->dvsize += psize;
+        m->dv = p;
+        set_size_and_pinuse_of_free_chunk(p, dsize);
+        return;
+      }
+      else {
+        size_t nsize = chunksize(next);
+        psize += nsize;
+        unlink_chunk(m, next, nsize);
+        set_size_and_pinuse_of_free_chunk(p, psize);
+        if (p == m->dv) {
+          m->dvsize = psize;
+          return;
+        }
+      }
+    }
+    else {
+      set_free_with_pinuse(p, psize, next);
+    }
+    insert_chunk(m, p, psize);
+  }
+  else {
+    CORRUPTION_ERROR_ACTION(m);
+  }
+}
+
+/* ---------------------------- malloc --------------------------- */
+
+/* allocate a large request from the best fitting chunk in a treebin */
+static void* tmalloc_large(mstate m, size_t nb) {
+  tchunkptr v = 0;
+  size_t rsize = -nb; /* Unsigned negation */
+  tchunkptr t;
+  bindex_t idx;
+  compute_tree_index(nb, idx);
+  if ((t = *treebin_at(m, idx)) != 0) {
+    /* Traverse tree for this bin looking for node with size == nb */
+    size_t sizebits = nb << leftshift_for_tree_index(idx);
+    tchunkptr rst = 0;  /* The deepest untaken right subtree */
+    for (;;) {
+      tchunkptr rt;
+      size_t trem = chunksize(t) - nb;
+      if (trem < rsize) {
+        v = t;
+        if ((rsize = trem) == 0)
+          break;
+      }
+      rt = t->child[1];
+      t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1];
+      if (rt != 0 && rt != t)
+        rst = rt;
+      if (t == 0) {
+        t = rst; /* set t to least subtree holding sizes > nb */
+        break;
+      }
+      sizebits <<= 1;
+    }
+  }
+  if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */
+    binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap;
+    if (leftbits != 0) {
+      bindex_t i;
+      binmap_t leastbit = least_bit(leftbits);
+      compute_bit2idx(leastbit, i);
+      t = *treebin_at(m, i);
+    }
+  }
+
+  while (t != 0) { /* find smallest of tree or subtree */
+    size_t trem = chunksize(t) - nb;
+    if (trem < rsize) {
+      rsize = trem;
+      v = t;
+    }
+    t = leftmost_child(t);
+  }
+
+  /*  If dv is a better fit, return 0 so malloc will use it */
+  if (v != 0 && rsize < (size_t)(m->dvsize - nb)) {
+    if (RTCHECK(ok_address(m, v))) { /* split */
+      mchunkptr r = chunk_plus_offset(v, nb);
+      assert(chunksize(v) == rsize + nb);
+      if (RTCHECK(ok_next(v, r))) {
+        unlink_large_chunk(m, v);
+        if (rsize < MIN_CHUNK_SIZE)
+          set_inuse_and_pinuse(m, v, (rsize + nb));
+        else {
+          set_size_and_pinuse_of_inuse_chunk(m, v, nb);
+          set_size_and_pinuse_of_free_chunk(r, rsize);
+          insert_chunk(m, r, rsize);
+        }
+        return chunk2mem(v);
+      }
+    }
+    CORRUPTION_ERROR_ACTION(m);
+  }
+  return 0;
+}
+
+/* allocate a small request from the best fitting chunk in a treebin */
+static void* tmalloc_small(mstate m, size_t nb) {
+  tchunkptr t, v;
+  size_t rsize;
+  bindex_t i;
+  binmap_t leastbit = least_bit(m->treemap);
+  compute_bit2idx(leastbit, i);
+  v = t = *treebin_at(m, i);
+  rsize = chunksize(t) - nb;
+
+  while ((t = leftmost_child(t)) != 0) {
+    size_t trem = chunksize(t) - nb;
+    if (trem < rsize) {
+      rsize = trem;
+      v = t;
+    }
+  }
+
+  if (RTCHECK(ok_address(m, v))) {
+    mchunkptr r = chunk_plus_offset(v, nb);
+    assert(chunksize(v) == rsize + nb);
+    if (RTCHECK(ok_next(v, r))) {
+      unlink_large_chunk(m, v);
+      if (rsize < MIN_CHUNK_SIZE)
+        set_inuse_and_pinuse(m, v, (rsize + nb));
+      else {
+        set_size_and_pinuse_of_inuse_chunk(m, v, nb);
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        replace_dv(m, r, rsize);
+      }
+      return chunk2mem(v);
+    }
+  }
+
+  CORRUPTION_ERROR_ACTION(m);
+  return 0;
+}
+
+#if !ONLY_MSPACES
+
+void* dlmalloc(size_t bytes) {
+  /*
+     Basic algorithm:
+     If a small request (< 256 bytes minus per-chunk overhead):
+       1. If one exists, use a remainderless chunk in associated smallbin.
+          (Remainderless means that there are too few excess bytes to
+          represent as a chunk.)
+       2. If it is big enough, use the dv chunk, which is normally the
+          chunk adjacent to the one used for the most recent small request.
+       3. If one exists, split the smallest available chunk in a bin,
+          saving remainder in dv.
+       4. If it is big enough, use the top chunk.
+       5. If available, get memory from system and use it
+     Otherwise, for a large request:
+       1. Find the smallest available binned chunk that fits, and use it
+          if it is better fitting than dv chunk, splitting if necessary.
+       2. If better fitting than any binned chunk, use the dv chunk.
+       3. If it is big enough, use the top chunk.
+       4. If request size >= mmap threshold, try to directly mmap this chunk.
+       5. If available, get memory from system and use it
+
+     The ugly goto's here ensure that postaction occurs along all paths.
+  */
+
+#if USE_LOCKS
+  ensure_initialization(); /* initialize in sys_alloc if not using locks */
+#endif
+
+  if (!PREACTION(gm)) {
+    void* mem;
+    size_t nb;
+    if (bytes <= MAX_SMALL_REQUEST) {
+      bindex_t idx;
+      binmap_t smallbits;
+      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
+      idx = small_index(nb);
+      smallbits = gm->smallmap >> idx;
+
+      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
+        mchunkptr b, p;
+        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
+        b = smallbin_at(gm, idx);
+        p = b->fd;
+        assert(chunksize(p) == small_index2size(idx));
+        unlink_first_small_chunk(gm, b, p, idx);
+        set_inuse_and_pinuse(gm, p, small_index2size(idx));
+        mem = chunk2mem(p);
+        check_malloced_chunk(gm, mem, nb);
+        goto postaction;
+      }
+
+      else if (nb > gm->dvsize) {
+        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
+          mchunkptr b, p, r;
+          size_t rsize;
+          bindex_t i;
+          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
+          binmap_t leastbit = least_bit(leftbits);
+          compute_bit2idx(leastbit, i);
+          b = smallbin_at(gm, i);
+          p = b->fd;
+          assert(chunksize(p) == small_index2size(i));
+          unlink_first_small_chunk(gm, b, p, i);
+          rsize = small_index2size(i) - nb;
+          /* Fit here cannot be remainderless if 4byte sizes */
+          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
+            set_inuse_and_pinuse(gm, p, small_index2size(i));
+          else {
+            set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+            r = chunk_plus_offset(p, nb);
+            set_size_and_pinuse_of_free_chunk(r, rsize);
+            replace_dv(gm, r, rsize);
+          }
+          mem = chunk2mem(p);
+          check_malloced_chunk(gm, mem, nb);
+          goto postaction;
+        }
+
+        else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) {
+          check_malloced_chunk(gm, mem, nb);
+          goto postaction;
+        }
+      }
+    }
+    else if (bytes >= MAX_REQUEST)
+      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
+    else {
+      nb = pad_request(bytes);
+      if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) {
+        check_malloced_chunk(gm, mem, nb);
+        goto postaction;
+      }
+    }
+
+    if (nb <= gm->dvsize) {
+      size_t rsize = gm->dvsize - nb;
+      mchunkptr p = gm->dv;
+      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
+        mchunkptr r = gm->dv = chunk_plus_offset(p, nb);
+        gm->dvsize = rsize;
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+      }
+      else { /* exhaust dv */
+        size_t dvs = gm->dvsize;
+        gm->dvsize = 0;
+        gm->dv = 0;
+        set_inuse_and_pinuse(gm, p, dvs);
+      }
+      mem = chunk2mem(p);
+      check_malloced_chunk(gm, mem, nb);
+      goto postaction;
+    }
+
+    else if (nb < gm->topsize) { /* Split top */
+      size_t rsize = gm->topsize -= nb;
+      mchunkptr p = gm->top;
+      mchunkptr r = gm->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(gm, p, nb);
+      mem = chunk2mem(p);
+      check_top_chunk(gm, gm->top);
+      check_malloced_chunk(gm, mem, nb);
+      goto postaction;
+    }
+
+    mem = sys_alloc(gm, nb);
+
+  postaction:
+    POSTACTION(gm);
+    return mem;
+  }
+
+  return 0;
+}
+
+/* ---------------------------- free --------------------------- */
+
+void dlfree(void* mem) {
+  /*
+     Consolidate freed chunks with preceeding or succeeding bordering
+     free chunks, if they exist, and then place in a bin.  Intermixed
+     with special cases for top, dv, mmapped chunks, and usage errors.
+  */
+
+  if (mem != 0) {
+    mchunkptr p  = mem2chunk(mem);
+#if FOOTERS
+    mstate fm = get_mstate_for(p);
+    if (!ok_magic(fm)) {
+      USAGE_ERROR_ACTION(fm, p);
+      return;
+    }
+#else /* FOOTERS */
+#define fm gm
+#endif /* FOOTERS */
+    if (!PREACTION(fm)) {
+      check_inuse_chunk(fm, p);
+      if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
+        size_t psize = chunksize(p);
+        mchunkptr next = chunk_plus_offset(p, psize);
+        if (!pinuse(p)) {
+          size_t prevsize = p->prev_foot;
+          if (is_mmapped(p)) {
+            psize += prevsize + MMAP_FOOT_PAD;
+            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
+              fm->footprint -= psize;
+            goto postaction;
+          }
+          else {
+            mchunkptr prev = chunk_minus_offset(p, prevsize);
+            psize += prevsize;
+            p = prev;
+            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
+              if (p != fm->dv) {
+                unlink_chunk(fm, p, prevsize);
+              }
+              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
+                fm->dvsize = psize;
+                set_free_with_pinuse(p, psize, next);
+                goto postaction;
+              }
+            }
+            else
+              goto erroraction;
+          }
+        }
+
+        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
+          if (!cinuse(next)) {  /* consolidate forward */
+            if (next == fm->top) {
+              size_t tsize = fm->topsize += psize;
+              fm->top = p;
+              p->head = tsize | PINUSE_BIT;
+              if (p == fm->dv) {
+                fm->dv = 0;
+                fm->dvsize = 0;
+              }
+              if (should_trim(fm, tsize))
+                sys_trim(fm, 0);
+              goto postaction;
+            }
+            else if (next == fm->dv) {
+              size_t dsize = fm->dvsize += psize;
+              fm->dv = p;
+              set_size_and_pinuse_of_free_chunk(p, dsize);
+              goto postaction;
+            }
+            else {
+              size_t nsize = chunksize(next);
+              psize += nsize;
+              unlink_chunk(fm, next, nsize);
+              set_size_and_pinuse_of_free_chunk(p, psize);
+              if (p == fm->dv) {
+                fm->dvsize = psize;
+                goto postaction;
+              }
+            }
+          }
+          else
+            set_free_with_pinuse(p, psize, next);
+
+          if (is_small(psize)) {
+            insert_small_chunk(fm, p, psize);
+            check_free_chunk(fm, p);
+          }
+          else {
+            tchunkptr tp = (tchunkptr)p;
+            insert_large_chunk(fm, tp, psize);
+            check_free_chunk(fm, p);
+            if (--fm->release_checks == 0)
+              release_unused_segments(fm);
+          }
+          goto postaction;
+        }
+      }
+    erroraction:
+      USAGE_ERROR_ACTION(fm, p);
+    postaction:
+      POSTACTION(fm);
+    }
+  }
+#if !FOOTERS
+#undef fm
+#endif /* FOOTERS */
+}
+
+void* dlcalloc(size_t n_elements, size_t elem_size) {
+  void* mem;
+  size_t req = 0;
+  if (n_elements != 0) {
+    req = n_elements * elem_size;
+    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
+        (req / n_elements != elem_size))
+      req = MAX_SIZE_T; /* force downstream failure on overflow */
+  }
+  mem = dlmalloc(req);
+  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
+    memset(mem, 0, req);
+  return mem;
+}
+
+#endif /* !ONLY_MSPACES */
+
+/* ------------ Internal support for realloc, memalign, etc -------------- */
+
+/* Try to realloc; only in-place unless can_move true */
+static mchunkptr try_realloc_chunk(mstate m, mchunkptr p, size_t nb,
+                                   int can_move) {
+  mchunkptr newp = 0;
+  size_t oldsize = chunksize(p);
+  mchunkptr next = chunk_plus_offset(p, oldsize);
+  if (RTCHECK(ok_address(m, p) && ok_inuse(p) &&
+              ok_next(p, next) && ok_pinuse(next))) {
+    if (is_mmapped(p)) {
+      newp = mmap_resize(m, p, nb, can_move);
+    }
+    else if (oldsize >= nb) {             /* already big enough */
+      size_t rsize = oldsize - nb;
+      if (rsize >= MIN_CHUNK_SIZE) {      /* split off remainder */
+        mchunkptr r = chunk_plus_offset(p, nb);
+        set_inuse(m, p, nb);
+        set_inuse(m, r, rsize);
+        dispose_chunk(m, r, rsize);
+      }
+      newp = p;
+    }
+    else if (next == m->top) {  /* extend into top */
+      if (oldsize + m->topsize > nb) {
+        size_t newsize = oldsize + m->topsize;
+        size_t newtopsize = newsize - nb;
+        mchunkptr newtop = chunk_plus_offset(p, nb);
+        set_inuse(m, p, nb);
+        newtop->head = newtopsize |PINUSE_BIT;
+        m->top = newtop;
+        m->topsize = newtopsize;
+        newp = p;
+      }
+    }
+    else if (next == m->dv) { /* extend into dv */
+      size_t dvs = m->dvsize;
+      if (oldsize + dvs >= nb) {
+        size_t dsize = oldsize + dvs - nb;
+        if (dsize >= MIN_CHUNK_SIZE) {
+          mchunkptr r = chunk_plus_offset(p, nb);
+          mchunkptr n = chunk_plus_offset(r, dsize);
+          set_inuse(m, p, nb);
+          set_size_and_pinuse_of_free_chunk(r, dsize);
+          clear_pinuse(n);
+          m->dvsize = dsize;
+          m->dv = r;
+        }
+        else { /* exhaust dv */
+          size_t newsize = oldsize + dvs;
+          set_inuse(m, p, newsize);
+          m->dvsize = 0;
+          m->dv = 0;
+        }
+        newp = p;
+      }
+    }
+    else if (!cinuse(next)) { /* extend into next free chunk */
+      size_t nextsize = chunksize(next);
+      if (oldsize + nextsize >= nb) {
+        size_t rsize = oldsize + nextsize - nb;
+        unlink_chunk(m, next, nextsize);
+        if (rsize < MIN_CHUNK_SIZE) {
+          size_t newsize = oldsize + nextsize;
+          set_inuse(m, p, newsize);
+        }
+        else {
+          mchunkptr r = chunk_plus_offset(p, nb);
+          set_inuse(m, p, nb);
+          set_inuse(m, r, rsize);
+          dispose_chunk(m, r, rsize);
+        }
+        newp = p;
+      }
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(m, chunk2mem(p));
+  }
+  return newp;
+}
+
+static void* internal_memalign(mstate m, size_t alignment, size_t bytes) {
+  void* mem = 0;
+  if (alignment <  MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */
+    alignment = MIN_CHUNK_SIZE;
+  if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */
+    size_t a = MALLOC_ALIGNMENT << 1;
+    while (a < alignment) a <<= 1;
+    alignment = a;
+  }
+  if (bytes >= MAX_REQUEST - alignment) {
+    if (m != 0)  { /* Test isn't needed but avoids compiler warning */
+      MALLOC_FAILURE_ACTION;
+    }
+  }
+  else {
+    size_t nb = request2size(bytes);
+    size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD;
+    mem = internal_malloc(m, req);
+    if (mem != 0) {
+      mchunkptr p = mem2chunk(mem);
+      if (PREACTION(m))
+        return 0;
+      if ((((size_t)(mem)) & (alignment - 1)) != 0) { /* misaligned */
+        /*
+          Find an aligned spot inside chunk.  Since we need to give
+          back leading space in a chunk of at least MIN_CHUNK_SIZE, if
+          the first calculation places us at a spot with less than
+          MIN_CHUNK_SIZE leader, we can move to the next aligned spot.
+          We've allocated enough total room so that this is always
+          possible.
+        */
+        char* br = (char*)mem2chunk((size_t)(((size_t)((char*)mem + alignment -
+                                                       SIZE_T_ONE)) &
+                                             -alignment));
+        char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)?
+          br : br+alignment;
+        mchunkptr newp = (mchunkptr)pos;
+        size_t leadsize = pos - (char*)(p);
+        size_t newsize = chunksize(p) - leadsize;
+
+        if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */
+          newp->prev_foot = p->prev_foot + leadsize;
+          newp->head = newsize;
+        }
+        else { /* Otherwise, give back leader, use the rest */
+          set_inuse(m, newp, newsize);
+          set_inuse(m, p, leadsize);
+          dispose_chunk(m, p, leadsize);
+        }
+        p = newp;
+      }
+
+      /* Give back spare room at the end */
+      if (!is_mmapped(p)) {
+        size_t size = chunksize(p);
+        if (size > nb + MIN_CHUNK_SIZE) {
+          size_t remainder_size = size - nb;
+          mchunkptr remainder = chunk_plus_offset(p, nb);
+          set_inuse(m, p, nb);
+          set_inuse(m, remainder, remainder_size);
+          dispose_chunk(m, remainder, remainder_size);
+        }
+      }
+
+      mem = chunk2mem(p);
+      assert (chunksize(p) >= nb);
+      assert(((size_t)mem & (alignment - 1)) == 0);
+      check_inuse_chunk(m, p);
+      POSTACTION(m);
+    }
+  }
+  return mem;
+}
+
+/*
+  Common support for independent_X routines, handling
+    all of the combinations that can result.
+  The opts arg has:
+    bit 0 set if all elements are same size (using sizes[0])
+    bit 1 set if elements should be zeroed
+*/
+static void** ialloc(mstate m,
+                     size_t n_elements,
+                     size_t* sizes,
+                     int opts,
+                     void* chunks[]) {
+
+  size_t    element_size;   /* chunksize of each element, if all same */
+  size_t    contents_size;  /* total size of elements */
+  size_t    array_size;     /* request size of pointer array */
+  void*     mem;            /* malloced aggregate space */
+  mchunkptr p;              /* corresponding chunk */
+  size_t    remainder_size; /* remaining bytes while splitting */
+  void**    marray;         /* either "chunks" or malloced ptr array */
+  mchunkptr array_chunk;    /* chunk for malloced ptr array */
+  flag_t    was_enabled;    /* to disable mmap */
+  size_t    size;
+  size_t    i;
+
+  ensure_initialization();
+  /* compute array length, if needed */
+  if (chunks != 0) {
+    if (n_elements == 0)
+      return chunks; /* nothing to do */
+    marray = chunks;
+    array_size = 0;
+  }
+  else {
+    /* if empty req, must still return chunk representing empty array */
+    if (n_elements == 0)
+      return (void**)internal_malloc(m, 0);
+    marray = 0;
+    array_size = request2size(n_elements * (sizeof(void*)));
+  }
+
+  /* compute total element size */
+  if (opts & 0x1) { /* all-same-size */
+    element_size = request2size(*sizes);
+    contents_size = n_elements * element_size;
+  }
+  else { /* add up all the sizes */
+    element_size = 0;
+    contents_size = 0;
+    for (i = 0; i != n_elements; ++i)
+      contents_size += request2size(sizes[i]);
+  }
+
+  size = contents_size + array_size;
+
+  /*
+     Allocate the aggregate chunk.  First disable direct-mmapping so
+     malloc won't use it, since we would not be able to later
+     free/realloc space internal to a segregated mmap region.
+  */
+  was_enabled = use_mmap(m);
+  disable_mmap(m);
+  mem = internal_malloc(m, size - CHUNK_OVERHEAD);
+  if (was_enabled)
+    enable_mmap(m);
+  if (mem == 0)
+    return 0;
+
+  if (PREACTION(m)) return 0;
+  p = mem2chunk(mem);
+  remainder_size = chunksize(p);
+
+  assert(!is_mmapped(p));
+
+  if (opts & 0x2) {       /* optionally clear the elements */
+    memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size);
+  }
+
+  /* If not provided, allocate the pointer array as final part of chunk */
+  if (marray == 0) {
+    size_t  array_chunk_size;
+    array_chunk = chunk_plus_offset(p, contents_size);
+    array_chunk_size = remainder_size - contents_size;
+    marray = (void**) (chunk2mem(array_chunk));
+    set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size);
+    remainder_size = contents_size;
+  }
+
+  /* split out elements */
+  for (i = 0; ; ++i) {
+    marray[i] = chunk2mem(p);
+    if (i != n_elements-1) {
+      if (element_size != 0)
+        size = element_size;
+      else
+        size = request2size(sizes[i]);
+      remainder_size -= size;
+      set_size_and_pinuse_of_inuse_chunk(m, p, size);
+      p = chunk_plus_offset(p, size);
+    }
+    else { /* the final element absorbs any overallocation slop */
+      set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size);
+      break;
+    }
+  }
+
+#if DEBUG
+  if (marray != chunks) {
+    /* final element must have exactly exhausted chunk */
+    if (element_size != 0) {
+      assert(remainder_size == element_size);
+    }
+    else {
+      assert(remainder_size == request2size(sizes[i]));
+    }
+    check_inuse_chunk(m, mem2chunk(marray));
+  }
+  for (i = 0; i != n_elements; ++i)
+    check_inuse_chunk(m, mem2chunk(marray[i]));
+
+#endif /* DEBUG */
+
+  POSTACTION(m);
+  return marray;
+}
+
+/* Try to free all pointers in the given array.
+   Note: this could be made faster, by delaying consolidation,
+   at the price of disabling some user integrity checks, We
+   still optimize some consolidations by combining adjacent
+   chunks before freeing, which will occur often if allocated
+   with ialloc or the array is sorted.
+*/
+static size_t internal_bulk_free(mstate m, void* array[], size_t nelem) {
+  size_t unfreed = 0;
+  if (!PREACTION(m)) {
+    void** a;
+    void** fence = &(array[nelem]);
+    for (a = array; a != fence; ++a) {
+      void* mem = *a;
+      if (mem != 0) {
+        mchunkptr p = mem2chunk(mem);
+        size_t psize = chunksize(p);
+#if FOOTERS
+        if (get_mstate_for(p) != m) {
+          ++unfreed;
+          continue;
+        }
+#endif
+        check_inuse_chunk(m, p);
+        *a = 0;
+        if (RTCHECK(ok_address(m, p) && ok_inuse(p))) {
+          void ** b = a + 1; /* try to merge with next chunk */
+          mchunkptr next = next_chunk(p);
+          if (b != fence && *b == chunk2mem(next)) {
+            size_t newsize = chunksize(next) + psize;
+            set_inuse(m, p, newsize);
+            *b = chunk2mem(p);
+          }
+          else
+            dispose_chunk(m, p, psize);
+        }
+        else {
+          CORRUPTION_ERROR_ACTION(m);
+          break;
+        }
+      }
+    }
+    if (should_trim(m, m->topsize))
+      sys_trim(m, 0);
+    POSTACTION(m);
+  }
+  return unfreed;
+}
+
+/* Traversal */
+#if MALLOC_INSPECT_ALL
+static void internal_inspect_all(mstate m,
+                                 void(*handler)(void *start,
+                                                void *end,
+                                                size_t used_bytes,
+                                                void* callback_arg),
+                                 void* arg) {
+  if (is_initialized(m)) {
+    mchunkptr top = m->top;
+    msegmentptr s;
+    for (s = &m->seg; s != 0; s = s->next) {
+      mchunkptr q = align_as_chunk(s->base);
+      while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) {
+        mchunkptr next = next_chunk(q);
+        size_t sz = chunksize(q);
+        size_t used;
+        void* start;
+        if (is_inuse(q)) {
+          used = sz - CHUNK_OVERHEAD; /* must not be mmapped */
+          start = chunk2mem(q);
+        }
+        else {
+          used = 0;
+          if (is_small(sz)) {     /* offset by possible bookkeeping */
+            start = (void*)((char*)q + sizeof(struct malloc_chunk));
+          }
+          else {
+            start = (void*)((char*)q + sizeof(struct malloc_tree_chunk));
+          }
+        }
+        if (start < (void*)next)  /* skip if all space is bookkeeping */
+          handler(start, next, used, arg);
+        if (q == top)
+          break;
+        q = next;
+      }
+    }
+  }
+}
+#endif /* MALLOC_INSPECT_ALL */
+
+/* ------------------ Exported realloc, memalign, etc -------------------- */
+
+#if !ONLY_MSPACES
+
+void* dlrealloc(void* oldmem, size_t bytes) {
+  void* mem = 0;
+  if (oldmem == 0) {
+    mem = dlmalloc(bytes);
+  }
+  else if (bytes >= MAX_REQUEST) {
+    MALLOC_FAILURE_ACTION;
+  }
+#ifdef REALLOC_ZERO_BYTES_FREES
+  else if (bytes == 0) {
+    dlfree(oldmem);
+  }
+#endif /* REALLOC_ZERO_BYTES_FREES */
+  else {
+    size_t nb = request2size(bytes);
+    mchunkptr oldp = mem2chunk(oldmem);
+#if ! FOOTERS
+    mstate m = gm;
+#else /* FOOTERS */
+    mstate m = get_mstate_for(oldp);
+    if (!ok_magic(m)) {
+      USAGE_ERROR_ACTION(m, oldmem);
+      return 0;
+    }
+#endif /* FOOTERS */
+    if (!PREACTION(m)) {
+      mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);
+      POSTACTION(m);
+      if (newp != 0) {
+        check_inuse_chunk(m, newp);
+        mem = chunk2mem(newp);
+      }
+      else {
+        mem = internal_malloc(m, bytes);
+        if (mem != 0) {
+          size_t oc = chunksize(oldp) - overhead_for(oldp);
+          memcpy(mem, oldmem, (oc < bytes)? oc : bytes);
+          internal_free(m, oldmem);
+        }
+      }
+    }
+  }
+  return mem;
+}
+
+void* dlrealloc_in_place(void* oldmem, size_t bytes) {
+  void* mem = 0;
+  if (oldmem != 0) {
+    if (bytes >= MAX_REQUEST) {
+      MALLOC_FAILURE_ACTION;
+    }
+    else {
+      size_t nb = request2size(bytes);
+      mchunkptr oldp = mem2chunk(oldmem);
+#if ! FOOTERS
+      mstate m = gm;
+#else /* FOOTERS */
+      mstate m = get_mstate_for(oldp);
+      if (!ok_magic(m)) {
+        USAGE_ERROR_ACTION(m, oldmem);
+        return 0;
+      }
+#endif /* FOOTERS */
+      if (!PREACTION(m)) {
+        mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);
+        POSTACTION(m);
+        if (newp == oldp) {
+          check_inuse_chunk(m, newp);
+          mem = oldmem;
+        }
+      }
+    }
+  }
+  return mem;
+}
+
+void* dlmemalign(size_t alignment, size_t bytes) {
+  if (alignment <= MALLOC_ALIGNMENT) {
+    return dlmalloc(bytes);
+  }
+  return internal_memalign(gm, alignment, bytes);
+}
+
+int dlposix_memalign(void** pp, size_t alignment, size_t bytes) {
+  void* mem = 0;
+  if (alignment == MALLOC_ALIGNMENT)
+    mem = dlmalloc(bytes);
+  else {
+    size_t d = alignment / sizeof(void*);
+    size_t r = alignment % sizeof(void*);
+    if (r != 0 || d == 0 || (d & (d-SIZE_T_ONE)) != 0)
+      return EINVAL;
+    else if (bytes <= MAX_REQUEST - alignment) {
+      if (alignment <  MIN_CHUNK_SIZE)
+        alignment = MIN_CHUNK_SIZE;
+      mem = internal_memalign(gm, alignment, bytes);
+    }
+  }
+  if (mem == 0)
+    return ENOMEM;
+  else {
+    *pp = mem;
+    return 0;
+  }
+}
+
+void* dlvalloc(size_t bytes) {
+  size_t pagesz;
+  ensure_initialization();
+  pagesz = mparams.page_size;
+  return dlmemalign(pagesz, bytes);
+}
+
+void* dlpvalloc(size_t bytes) {
+  size_t pagesz;
+  ensure_initialization();
+  pagesz = mparams.page_size;
+  return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE));
+}
+
+void** dlindependent_calloc(size_t n_elements, size_t elem_size,
+                            void* chunks[]) {
+  size_t sz = elem_size; /* serves as 1-element array */
+  return ialloc(gm, n_elements, &sz, 3, chunks);
+}
+
+void** dlindependent_comalloc(size_t n_elements, size_t sizes[],
+                              void* chunks[]) {
+  return ialloc(gm, n_elements, sizes, 0, chunks);
+}
+
+size_t dlbulk_free(void* array[], size_t nelem) {
+  return internal_bulk_free(gm, array, nelem);
+}
+
+#if MALLOC_INSPECT_ALL
+void dlmalloc_inspect_all(void(*handler)(void *start,
+                                         void *end,
+                                         size_t used_bytes,
+                                         void* callback_arg),
+                          void* arg) {
+  ensure_initialization();
+  if (!PREACTION(gm)) {
+    internal_inspect_all(gm, handler, arg);
+    POSTACTION(gm);
+  }
+}
+#endif /* MALLOC_INSPECT_ALL */
+
+int dlmalloc_trim(size_t pad) {
+  int result = 0;
+  ensure_initialization();
+  if (!PREACTION(gm)) {
+    result = sys_trim(gm, pad);
+    POSTACTION(gm);
+  }
+  return result;
+}
+
+size_t dlmalloc_footprint(void) {
+  return gm->footprint;
+}
+
+size_t dlmalloc_max_footprint(void) {
+  return gm->max_footprint;
+}
+
+size_t dlmalloc_footprint_limit(void) {
+  size_t maf = gm->footprint_limit;
+  return maf == 0 ? MAX_SIZE_T : maf;
+}
+
+size_t dlmalloc_set_footprint_limit(size_t bytes) {
+  size_t result;  /* invert sense of 0 */
+  if (bytes == 0)
+    result = granularity_align(1); /* Use minimal size */
+  if (bytes == MAX_SIZE_T)
+    result = 0;                    /* disable */
+  else
+    result = granularity_align(bytes);
+  return gm->footprint_limit = result;
+}
+
+#if !NO_MALLINFO
+struct mallinfo dlmallinfo(void) {
+  return internal_mallinfo(gm);
+}
+#endif /* NO_MALLINFO */
+
+#if !NO_MALLOC_STATS
+void dlmalloc_stats() {
+  internal_malloc_stats(gm);
+}
+#endif /* NO_MALLOC_STATS */
+
+int dlmallopt(int param_number, int value) {
+  return change_mparam(param_number, value);
+}
+
+size_t dlmalloc_usable_size(void* mem) {
+  if (mem != 0) {
+    mchunkptr p = mem2chunk(mem);
+    if (is_inuse(p))
+      return chunksize(p) - overhead_for(p);
+  }
+  return 0;
+}
+
+#endif /* !ONLY_MSPACES */
+
+/* ----------------------------- user mspaces ---------------------------- */
+
+#if MSPACES
+
+static mstate init_user_mstate(char* tbase, size_t tsize) {
+  size_t msize = pad_request(sizeof(struct malloc_state));
+  mchunkptr mn;
+  mchunkptr msp = align_as_chunk(tbase);
+  mstate m = (mstate)(chunk2mem(msp));
+  memset(m, 0, msize);
+  (void)INITIAL_LOCK(&m->mutex);
+  msp->head = (msize|INUSE_BITS);
+  m->seg.base = m->least_addr = tbase;
+  m->seg.size = m->footprint = m->max_footprint = tsize;
+  m->magic = mparams.magic;
+  m->release_checks = MAX_RELEASE_CHECK_RATE;
+  m->mflags = mparams.default_mflags;
+  m->extp = 0;
+  m->exts = 0;
+  disable_contiguous(m);
+  init_bins(m);
+  mn = next_chunk(mem2chunk(m));
+  init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE);
+  check_top_chunk(m, m->top);
+  return m;
+}
+
+mspace create_mspace(size_t capacity, int locked) {
+  mstate m = 0;
+  size_t msize;
+  ensure_initialization();
+  msize = pad_request(sizeof(struct malloc_state));
+  if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
+    size_t rs = ((capacity == 0)? mparams.granularity :
+                 (capacity + TOP_FOOT_SIZE + msize));
+    size_t tsize = granularity_align(rs);
+    char* tbase = (char*)(CALL_MMAP(tsize));
+    if (tbase != CMFAIL) {
+      m = init_user_mstate(tbase, tsize);
+      m->seg.sflags = USE_MMAP_BIT;
+      set_lock(m, locked);
+    }
+  }
+  return (mspace)m;
+}
+
+mspace create_mspace_with_base(void* base, size_t capacity, int locked) {
+  mstate m = 0;
+  size_t msize;
+  ensure_initialization();
+  msize = pad_request(sizeof(struct malloc_state));
+  if (capacity > msize + TOP_FOOT_SIZE &&
+      capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) {
+    m = init_user_mstate((char*)base, capacity);
+    m->seg.sflags = EXTERN_BIT;
+    set_lock(m, locked);
+  }
+  return (mspace)m;
+}
+
+int mspace_track_large_chunks(mspace msp, int enable) {
+  int ret = 0;
+  mstate ms = (mstate)msp;
+  if (!PREACTION(ms)) {
+    if (!use_mmap(ms)) {
+      ret = 1;
+    }
+    if (!enable) {
+      enable_mmap(ms);
+    } else {
+      disable_mmap(ms);
+    }
+    POSTACTION(ms);
+  }
+  return ret;
+}
+
+size_t destroy_mspace(mspace msp) {
+  size_t freed = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    msegmentptr sp = &ms->seg;
+    (void)DESTROY_LOCK(&ms->mutex); /* destroy before unmapped */
+    while (sp != 0) {
+      char* base = sp->base;
+      size_t size = sp->size;
+      flag_t flag = sp->sflags;
+      (void)base; /* placate people compiling -Wunused-variable */
+      sp = sp->next;
+      if ((flag & USE_MMAP_BIT) && !(flag & EXTERN_BIT) &&
+          CALL_MUNMAP(base, size) == 0)
+        freed += size;
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return freed;
+}
+
+/*
+  mspace versions of routines are near-clones of the global
+  versions. This is not so nice but better than the alternatives.
+*/
+
+void* mspace_malloc(mspace msp, size_t bytes) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  if (!PREACTION(ms)) {
+    void* mem;
+    size_t nb;
+    if (bytes <= MAX_SMALL_REQUEST) {
+      bindex_t idx;
+      binmap_t smallbits;
+      nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes);
+      idx = small_index(nb);
+      smallbits = ms->smallmap >> idx;
+
+      if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */
+        mchunkptr b, p;
+        idx += ~smallbits & 1;       /* Uses next bin if idx empty */
+        b = smallbin_at(ms, idx);
+        p = b->fd;
+        assert(chunksize(p) == small_index2size(idx));
+        unlink_first_small_chunk(ms, b, p, idx);
+        set_inuse_and_pinuse(ms, p, small_index2size(idx));
+        mem = chunk2mem(p);
+        check_malloced_chunk(ms, mem, nb);
+        goto postaction;
+      }
+
+      else if (nb > ms->dvsize) {
+        if (smallbits != 0) { /* Use chunk in next nonempty smallbin */
+          mchunkptr b, p, r;
+          size_t rsize;
+          bindex_t i;
+          binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx));
+          binmap_t leastbit = least_bit(leftbits);
+          compute_bit2idx(leastbit, i);
+          b = smallbin_at(ms, i);
+          p = b->fd;
+          assert(chunksize(p) == small_index2size(i));
+          unlink_first_small_chunk(ms, b, p, i);
+          rsize = small_index2size(i) - nb;
+          /* Fit here cannot be remainderless if 4byte sizes */
+          if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE)
+            set_inuse_and_pinuse(ms, p, small_index2size(i));
+          else {
+            set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+            r = chunk_plus_offset(p, nb);
+            set_size_and_pinuse_of_free_chunk(r, rsize);
+            replace_dv(ms, r, rsize);
+          }
+          mem = chunk2mem(p);
+          check_malloced_chunk(ms, mem, nb);
+          goto postaction;
+        }
+
+        else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) {
+          check_malloced_chunk(ms, mem, nb);
+          goto postaction;
+        }
+      }
+    }
+    else if (bytes >= MAX_REQUEST)
+      nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */
+    else {
+      nb = pad_request(bytes);
+      if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) {
+        check_malloced_chunk(ms, mem, nb);
+        goto postaction;
+      }
+    }
+
+    if (nb <= ms->dvsize) {
+      size_t rsize = ms->dvsize - nb;
+      mchunkptr p = ms->dv;
+      if (rsize >= MIN_CHUNK_SIZE) { /* split dv */
+        mchunkptr r = ms->dv = chunk_plus_offset(p, nb);
+        ms->dvsize = rsize;
+        set_size_and_pinuse_of_free_chunk(r, rsize);
+        set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+      }
+      else { /* exhaust dv */
+        size_t dvs = ms->dvsize;
+        ms->dvsize = 0;
+        ms->dv = 0;
+        set_inuse_and_pinuse(ms, p, dvs);
+      }
+      mem = chunk2mem(p);
+      check_malloced_chunk(ms, mem, nb);
+      goto postaction;
+    }
+
+    else if (nb < ms->topsize) { /* Split top */
+      size_t rsize = ms->topsize -= nb;
+      mchunkptr p = ms->top;
+      mchunkptr r = ms->top = chunk_plus_offset(p, nb);
+      r->head = rsize | PINUSE_BIT;
+      set_size_and_pinuse_of_inuse_chunk(ms, p, nb);
+      mem = chunk2mem(p);
+      check_top_chunk(ms, ms->top);
+      check_malloced_chunk(ms, mem, nb);
+      goto postaction;
+    }
+
+    mem = sys_alloc(ms, nb);
+
+  postaction:
+    POSTACTION(ms);
+    return mem;
+  }
+
+  return 0;
+}
+
+void mspace_free(mspace msp, void* mem) {
+  if (mem != 0) {
+    mchunkptr p  = mem2chunk(mem);
+#if FOOTERS
+    mstate fm = get_mstate_for(p);
+    (void)msp; /* placate people compiling -Wunused */
+#else /* FOOTERS */
+    mstate fm = (mstate)msp;
+#endif /* FOOTERS */
+    if (!ok_magic(fm)) {
+      USAGE_ERROR_ACTION(fm, p);
+      return;
+    }
+    if (!PREACTION(fm)) {
+      check_inuse_chunk(fm, p);
+      if (RTCHECK(ok_address(fm, p) && ok_inuse(p))) {
+        size_t psize = chunksize(p);
+        mchunkptr next = chunk_plus_offset(p, psize);
+        if (!pinuse(p)) {
+          size_t prevsize = p->prev_foot;
+          if (is_mmapped(p)) {
+            psize += prevsize + MMAP_FOOT_PAD;
+            if (CALL_MUNMAP((char*)p - prevsize, psize) == 0)
+              fm->footprint -= psize;
+            goto postaction;
+          }
+          else {
+            mchunkptr prev = chunk_minus_offset(p, prevsize);
+            psize += prevsize;
+            p = prev;
+            if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */
+              if (p != fm->dv) {
+                unlink_chunk(fm, p, prevsize);
+              }
+              else if ((next->head & INUSE_BITS) == INUSE_BITS) {
+                fm->dvsize = psize;
+                set_free_with_pinuse(p, psize, next);
+                goto postaction;
+              }
+            }
+            else
+              goto erroraction;
+          }
+        }
+
+        if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) {
+          if (!cinuse(next)) {  /* consolidate forward */
+            if (next == fm->top) {
+              size_t tsize = fm->topsize += psize;
+              fm->top = p;
+              p->head = tsize | PINUSE_BIT;
+              if (p == fm->dv) {
+                fm->dv = 0;
+                fm->dvsize = 0;
+              }
+              if (should_trim(fm, tsize))
+                sys_trim(fm, 0);
+              goto postaction;
+            }
+            else if (next == fm->dv) {
+              size_t dsize = fm->dvsize += psize;
+              fm->dv = p;
+              set_size_and_pinuse_of_free_chunk(p, dsize);
+              goto postaction;
+            }
+            else {
+              size_t nsize = chunksize(next);
+              psize += nsize;
+              unlink_chunk(fm, next, nsize);
+              set_size_and_pinuse_of_free_chunk(p, psize);
+              if (p == fm->dv) {
+                fm->dvsize = psize;
+                goto postaction;
+              }
+            }
+          }
+          else
+            set_free_with_pinuse(p, psize, next);
+
+          if (is_small(psize)) {
+            insert_small_chunk(fm, p, psize);
+            check_free_chunk(fm, p);
+          }
+          else {
+            tchunkptr tp = (tchunkptr)p;
+            insert_large_chunk(fm, tp, psize);
+            check_free_chunk(fm, p);
+            if (--fm->release_checks == 0)
+              release_unused_segments(fm);
+          }
+          goto postaction;
+        }
+      }
+    erroraction:
+      USAGE_ERROR_ACTION(fm, p);
+    postaction:
+      POSTACTION(fm);
+    }
+  }
+}
+
+void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) {
+  void* mem;
+  size_t req = 0;
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  if (n_elements != 0) {
+    req = n_elements * elem_size;
+    if (((n_elements | elem_size) & ~(size_t)0xffff) &&
+        (req / n_elements != elem_size))
+      req = MAX_SIZE_T; /* force downstream failure on overflow */
+  }
+  mem = internal_malloc(ms, req);
+  if (mem != 0 && calloc_must_clear(mem2chunk(mem)))
+    memset(mem, 0, req);
+  return mem;
+}
+
+void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) {
+  void* mem = 0;
+  if (oldmem == 0) {
+    mem = mspace_malloc(msp, bytes);
+  }
+  else if (bytes >= MAX_REQUEST) {
+    MALLOC_FAILURE_ACTION;
+  }
+#ifdef REALLOC_ZERO_BYTES_FREES
+  else if (bytes == 0) {
+    mspace_free(msp, oldmem);
+  }
+#endif /* REALLOC_ZERO_BYTES_FREES */
+  else {
+    size_t nb = request2size(bytes);
+    mchunkptr oldp = mem2chunk(oldmem);
+#if ! FOOTERS
+    mstate m = (mstate)msp;
+#else /* FOOTERS */
+    mstate m = get_mstate_for(oldp);
+    if (!ok_magic(m)) {
+      USAGE_ERROR_ACTION(m, oldmem);
+      return 0;
+    }
+#endif /* FOOTERS */
+    if (!PREACTION(m)) {
+      mchunkptr newp = try_realloc_chunk(m, oldp, nb, 1);
+      POSTACTION(m);
+      if (newp != 0) {
+        check_inuse_chunk(m, newp);
+        mem = chunk2mem(newp);
+      }
+      else {
+        mem = mspace_malloc(m, bytes);
+        if (mem != 0) {
+          size_t oc = chunksize(oldp) - overhead_for(oldp);
+          memcpy(mem, oldmem, (oc < bytes)? oc : bytes);
+          mspace_free(m, oldmem);
+        }
+      }
+    }
+  }
+  return mem;
+}
+
+void* mspace_realloc_in_place(mspace msp, void* oldmem, size_t bytes) {
+  void* mem = 0;
+  if (oldmem != 0) {
+    if (bytes >= MAX_REQUEST) {
+      MALLOC_FAILURE_ACTION;
+    }
+    else {
+      size_t nb = request2size(bytes);
+      mchunkptr oldp = mem2chunk(oldmem);
+#if ! FOOTERS
+      mstate m = (mstate)msp;
+#else /* FOOTERS */
+      mstate m = get_mstate_for(oldp);
+      (void)msp; /* placate people compiling -Wunused */
+      if (!ok_magic(m)) {
+        USAGE_ERROR_ACTION(m, oldmem);
+        return 0;
+      }
+#endif /* FOOTERS */
+      if (!PREACTION(m)) {
+        mchunkptr newp = try_realloc_chunk(m, oldp, nb, 0);
+        POSTACTION(m);
+        if (newp == oldp) {
+          check_inuse_chunk(m, newp);
+          mem = oldmem;
+        }
+      }
+    }
+  }
+  return mem;
+}
+
+void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  if (alignment <= MALLOC_ALIGNMENT)
+    return mspace_malloc(msp, bytes);
+  return internal_memalign(ms, alignment, bytes);
+}
+
+void** mspace_independent_calloc(mspace msp, size_t n_elements,
+                                 size_t elem_size, void* chunks[]) {
+  size_t sz = elem_size; /* serves as 1-element array */
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  return ialloc(ms, n_elements, &sz, 3, chunks);
+}
+
+void** mspace_independent_comalloc(mspace msp, size_t n_elements,
+                                   size_t sizes[], void* chunks[]) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+    return 0;
+  }
+  return ialloc(ms, n_elements, sizes, 0, chunks);
+}
+
+size_t mspace_bulk_free(mspace msp, void* array[], size_t nelem) {
+  return internal_bulk_free((mstate)msp, array, nelem);
+}
+
+#if MALLOC_INSPECT_ALL
+void mspace_inspect_all(mspace msp,
+                        void(*handler)(void *start,
+                                       void *end,
+                                       size_t used_bytes,
+                                       void* callback_arg),
+                        void* arg) {
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    if (!PREACTION(ms)) {
+      internal_inspect_all(ms, handler, arg);
+      POSTACTION(ms);
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+}
+#endif /* MALLOC_INSPECT_ALL */
+
+int mspace_trim(mspace msp, size_t pad) {
+  int result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    if (!PREACTION(ms)) {
+      result = sys_trim(ms, pad);
+      POSTACTION(ms);
+    }
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+#if !NO_MALLOC_STATS
+void mspace_malloc_stats(mspace msp) {
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    internal_malloc_stats(ms);
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+}
+#endif /* NO_MALLOC_STATS */
+
+size_t mspace_footprint(mspace msp) {
+  size_t result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    result = ms->footprint;
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+size_t mspace_max_footprint(mspace msp) {
+  size_t result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    result = ms->max_footprint;
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+size_t mspace_footprint_limit(mspace msp) {
+  size_t result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    size_t maf = ms->footprint_limit;
+    result = (maf == 0) ? MAX_SIZE_T : maf;
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+size_t mspace_set_footprint_limit(mspace msp, size_t bytes) {
+  size_t result = 0;
+  mstate ms = (mstate)msp;
+  if (ok_magic(ms)) {
+    if (bytes == 0)
+      result = granularity_align(1); /* Use minimal size */
+    if (bytes == MAX_SIZE_T)
+      result = 0;                    /* disable */
+    else
+      result = granularity_align(bytes);
+    ms->footprint_limit = result;
+  }
+  else {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return result;
+}
+
+#if !NO_MALLINFO
+struct mallinfo mspace_mallinfo(mspace msp) {
+  mstate ms = (mstate)msp;
+  if (!ok_magic(ms)) {
+    USAGE_ERROR_ACTION(ms,ms);
+  }
+  return internal_mallinfo(ms);
+}
+#endif /* NO_MALLINFO */
+
+size_t mspace_usable_size(const void* mem) {
+  if (mem != 0) {
+    mchunkptr p = mem2chunk(mem);
+    if (is_inuse(p))
+      return chunksize(p) - overhead_for(p);
+  }
+  return 0;
+}
+
+int mspace_mallopt(int param_number, int value) {
+  return change_mparam(param_number, value);
+}
+
+#endif /* MSPACES */
+
+
+/* -------------------- Alternative MORECORE functions ------------------- */
+
+/*
+  Guidelines for creating a custom version of MORECORE:
+
+  * For best performance, MORECORE should allocate in multiples of pagesize.
+  * MORECORE may allocate more memory than requested. (Or even less,
+      but this will usually result in a malloc failure.)
+  * MORECORE must not allocate memory when given argument zero, but
+      instead return one past the end address of memory from previous
+      nonzero call.
+  * For best performance, consecutive calls to MORECORE with positive
+      arguments should return increasing addresses, indicating that
+      space has been contiguously extended.
+  * Even though consecutive calls to MORECORE need not return contiguous
+      addresses, it must be OK for malloc'ed chunks to span multiple
+      regions in those cases where they do happen to be contiguous.
+  * MORECORE need not handle negative arguments -- it may instead
+      just return MFAIL when given negative arguments.
+      Negative arguments are always multiples of pagesize. MORECORE
+      must not misinterpret negative args as large positive unsigned
+      args. You can suppress all such calls from even occurring by defining
+      MORECORE_CANNOT_TRIM,
+
+  As an example alternative MORECORE, here is a custom allocator
+  kindly contributed for pre-OSX macOS.  It uses virtually but not
+  necessarily physically contiguous non-paged memory (locked in,
+  present and won't get swapped out).  You can use it by uncommenting
+  this section, adding some #includes, and setting up the appropriate
+  defines above:
+
+      #define MORECORE osMoreCore
+
+  There is also a shutdown routine that should somehow be called for
+  cleanup upon program exit.
+
+  #define MAX_POOL_ENTRIES 100
+  #define MINIMUM_MORECORE_SIZE  (64 * 1024U)
+  static int next_os_pool;
+  void *our_os_pools[MAX_POOL_ENTRIES];
+
+  void *osMoreCore(int size)
+  {
+    void *ptr = 0;
+    static void *sbrk_top = 0;
+
+    if (size > 0)
+    {
+      if (size < MINIMUM_MORECORE_SIZE)
+         size = MINIMUM_MORECORE_SIZE;
+      if (CurrentExecutionLevel() == kTaskLevel)
+         ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0);
+      if (ptr == 0)
+      {
+        return (void *) MFAIL;
+      }
+      // save ptrs so they can be freed during cleanup
+      our_os_pools[next_os_pool] = ptr;
+      next_os_pool++;
+      ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK);
+      sbrk_top = (char *) ptr + size;
+      return ptr;
+    }
+    else if (size < 0)
+    {
+      // we don't currently support shrink behavior
+      return (void *) MFAIL;
+    }
+    else
+    {
+      return sbrk_top;
+    }
+  }
+
+  // cleanup any allocated memory pools
+  // called as last thing before shutting down driver
+
+  void osCleanupMem(void)
+  {
+    void **ptr;
+
+    for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++)
+      if (*ptr)
+      {
+         PoolDeallocate(*ptr);
+         *ptr = 0;
+      }
+  }
+
+*/
+
+
+/* -----------------------------------------------------------------------
+History:
+    v2.8.6 Wed Aug 29 06:57:58 2012  Doug Lea
+      * fix bad comparison in dlposix_memalign
+      * don't reuse adjusted asize in sys_alloc
+      * add LOCK_AT_FORK -- thanks to Kirill Artamonov for the suggestion
+      * reduce compiler warnings -- thanks to all who reported/suggested these
+
+    v2.8.5 Sun May 22 10:26:02 2011  Doug Lea  (dl at gee)
+      * Always perform unlink checks unless INSECURE
+      * Add posix_memalign.
+      * Improve realloc to expand in more cases; expose realloc_in_place.
+        Thanks to Peter Buhr for the suggestion.
+      * Add footprint_limit, inspect_all, bulk_free. Thanks
+        to Barry Hayes and others for the suggestions.
+      * Internal refactorings to avoid calls while holding locks
+      * Use non-reentrant locks by default. Thanks to Roland McGrath
+        for the suggestion.
+      * Small fixes to mspace_destroy, reset_on_error.
+      * Various configuration extensions/changes. Thanks
+         to all who contributed these.
+
+    V2.8.4a Thu Apr 28 14:39:43 2011 (dl at gee.cs.oswego.edu)
+      * Update Creative Commons URL
+
+    V2.8.4 Wed May 27 09:56:23 2009  Doug Lea  (dl at gee)
+      * Use zeros instead of prev foot for is_mmapped
+      * Add mspace_track_large_chunks; thanks to Jean Brouwers
+      * Fix set_inuse in internal_realloc; thanks to Jean Brouwers
+      * Fix insufficient sys_alloc padding when using 16byte alignment
+      * Fix bad error check in mspace_footprint
+      * Adaptations for ptmalloc; thanks to Wolfram Gloger.
+      * Reentrant spin locks; thanks to Earl Chew and others
+      * Win32 improvements; thanks to Niall Douglas and Earl Chew
+      * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options
+      * Extension hook in malloc_state
+      * Various small adjustments to reduce warnings on some compilers
+      * Various configuration extensions/changes for more platforms. Thanks
+         to all who contributed these.
+
+    V2.8.3 Thu Sep 22 11:16:32 2005  Doug Lea  (dl at gee)
+      * Add max_footprint functions
+      * Ensure all appropriate literals are size_t
+      * Fix conditional compilation problem for some #define settings
+      * Avoid concatenating segments with the one provided
+        in create_mspace_with_base
+      * Rename some variables to avoid compiler shadowing warnings
+      * Use explicit lock initialization.
+      * Better handling of sbrk interference.
+      * Simplify and fix segment insertion, trimming and mspace_destroy
+      * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x
+      * Thanks especially to Dennis Flanagan for help on these.
+
+    V2.8.2 Sun Jun 12 16:01:10 2005  Doug Lea  (dl at gee)
+      * Fix memalign brace error.
+
+    V2.8.1 Wed Jun  8 16:11:46 2005  Doug Lea  (dl at gee)
+      * Fix improper #endif nesting in C++
+      * Add explicit casts needed for C++
+
+    V2.8.0 Mon May 30 14:09:02 2005  Doug Lea  (dl at gee)
+      * Use trees for large bins
+      * Support mspaces
+      * Use segments to unify sbrk-based and mmap-based system allocation,
+        removing need for emulation on most platforms without sbrk.
+      * Default safety checks
+      * Optional footer checks. Thanks to William Robertson for the idea.
+      * Internal code refactoring
+      * Incorporate suggestions and platform-specific changes.
+        Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas,
+        Aaron Bachmann,  Emery Berger, and others.
+      * Speed up non-fastbin processing enough to remove fastbins.
+      * Remove useless cfree() to avoid conflicts with other apps.
+      * Remove internal memcpy, memset. Compilers handle builtins better.
+      * Remove some options that no one ever used and rename others.
+
+    V2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
+      * Fix malloc_state bitmap array misdeclaration
+
+    V2.7.1 Thu Jul 25 10:58:03 2002  Doug Lea  (dl at gee)
+      * Allow tuning of FIRST_SORTED_BIN_SIZE
+      * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte.
+      * Better detection and support for non-contiguousness of MORECORE.
+        Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger
+      * Bypass most of malloc if no frees. Thanks To Emery Berger.
+      * Fix freeing of old top non-contiguous chunk im sysmalloc.
+      * Raised default trim and map thresholds to 256K.
+      * Fix mmap-related #defines. Thanks to Lubos Lunak.
+      * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield.
+      * Branch-free bin calculation
+      * Default trim and mmap thresholds now 256K.
+
+    V2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
+      * Introduce independent_comalloc and independent_calloc.
+        Thanks to Michael Pachos for motivation and help.
+      * Make optional .h file available
+      * Allow > 2GB requests on 32bit systems.
+      * new WIN32 sbrk, mmap, munmap, lock code from <Walter@GeNeSys-e.de>.
+        Thanks also to Andreas Mueller <a.mueller at paradatec.de>,
+        and Anonymous.
+      * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for
+        helping test this.)
+      * memalign: check alignment arg
+      * realloc: don't try to shift chunks backwards, since this
+        leads to  more fragmentation in some programs and doesn't
+        seem to help in any others.
+      * Collect all cases in malloc requiring system memory into sysmalloc
+      * Use mmap as backup to sbrk
+      * Place all internal state in malloc_state
+      * Introduce fastbins (although similar to 2.5.1)
+      * Many minor tunings and cosmetic improvements
+      * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK
+      * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS
+        Thanks to Tony E. Bennett <tbennett@nvidia.com> and others.
+      * Include errno.h to support default failure action.
+
+    V2.6.6 Sun Dec  5 07:42:19 1999  Doug Lea  (dl at gee)
+      * return null for negative arguments
+      * Added Several WIN32 cleanups from Martin C. Fong <mcfong at yahoo.com>
+         * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h'
+          (e.g. WIN32 platforms)
+         * Cleanup header file inclusion for WIN32 platforms
+         * Cleanup code to avoid Microsoft Visual C++ compiler complaints
+         * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing
+           memory allocation routines
+         * Set 'malloc_getpagesize' for WIN32 platforms (needs more work)
+         * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to
+           usage of 'assert' in non-WIN32 code
+         * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to
+           avoid infinite loop
+      * Always call 'fREe()' rather than 'free()'
+
+    V2.6.5 Wed Jun 17 15:57:31 1998  Doug Lea  (dl at gee)
+      * Fixed ordering problem with boundary-stamping
+
+    V2.6.3 Sun May 19 08:17:58 1996  Doug Lea  (dl at gee)
+      * Added pvalloc, as recommended by H.J. Liu
+      * Added 64bit pointer support mainly from Wolfram Gloger
+      * Added anonymously donated WIN32 sbrk emulation
+      * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen
+      * malloc_extend_top: fix mask error that caused wastage after
+        foreign sbrks
+      * Add linux mremap support code from HJ Liu
+
+    V2.6.2 Tue Dec  5 06:52:55 1995  Doug Lea  (dl at gee)
+      * Integrated most documentation with the code.
+      * Add support for mmap, with help from
+        Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
+      * Use last_remainder in more cases.
+      * Pack bins using idea from  colin@nyx10.cs.du.edu
+      * Use ordered bins instead of best-fit threshhold
+      * Eliminate block-local decls to simplify tracing and debugging.
+      * Support another case of realloc via move into top
+      * Fix error occuring when initial sbrk_base not word-aligned.
+      * Rely on page size for units instead of SBRK_UNIT to
+        avoid surprises about sbrk alignment conventions.
+      * Add mallinfo, mallopt. Thanks to Raymond Nijssen
+        (raymond@es.ele.tue.nl) for the suggestion.
+      * Add `pad' argument to malloc_trim and top_pad mallopt parameter.
+      * More precautions for cases where other routines call sbrk,
+        courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de).
+      * Added macros etc., allowing use in linux libc from
+        H.J. Lu (hjl@gnu.ai.mit.edu)
+      * Inverted this history list
+
+    V2.6.1 Sat Dec  2 14:10:57 1995  Doug Lea  (dl at gee)
+      * Re-tuned and fixed to behave more nicely with V2.6.0 changes.
+      * Removed all preallocation code since under current scheme
+        the work required to undo bad preallocations exceeds
+        the work saved in good cases for most test programs.
+      * No longer use return list or unconsolidated bins since
+        no scheme using them consistently outperforms those that don't
+        given above changes.
+      * Use best fit for very large chunks to prevent some worst-cases.
+      * Added some support for debugging
+
+    V2.6.0 Sat Nov  4 07:05:23 1995  Doug Lea  (dl at gee)
+      * Removed footers when chunks are in use. Thanks to
+        Paul Wilson (wilson@cs.texas.edu) for the suggestion.
+
+    V2.5.4 Wed Nov  1 07:54:51 1995  Doug Lea  (dl at gee)
+      * Added malloc_trim, with help from Wolfram Gloger
+        (wmglo@Dent.MED.Uni-Muenchen.DE).
+
+    V2.5.3 Tue Apr 26 10:16:01 1994  Doug Lea  (dl at g)
+
+    V2.5.2 Tue Apr  5 16:20:40 1994  Doug Lea  (dl at g)
+      * realloc: try to expand in both directions
+      * malloc: swap order of clean-bin strategy;
+      * realloc: only conditionally expand backwards
+      * Try not to scavenge used bins
+      * Use bin counts as a guide to preallocation
+      * Occasionally bin return list chunks in first scan
+      * Add a few optimizations from colin@nyx10.cs.du.edu
+
+    V2.5.1 Sat Aug 14 15:40:43 1993  Doug Lea  (dl at g)
+      * faster bin computation & slightly different binning
+      * merged all consolidations to one part of malloc proper
+         (eliminating old malloc_find_space & malloc_clean_bin)
+      * Scan 2 returns chunks (not just 1)
+      * Propagate failure in realloc if malloc returns 0
+      * Add stuff to allow compilation on non-ANSI compilers
+          from kpv@research.att.com
+
+    V2.5 Sat Aug  7 07:41:59 1993  Doug Lea  (dl at g.oswego.edu)
+      * removed potential for odd address access in prev_chunk
+      * removed dependency on getpagesize.h
+      * misc cosmetics and a bit more internal documentation
+      * anticosmetics: mangled names in macros to evade debugger strangeness
+      * tested on sparc, hp-700, dec-mips, rs6000
+          with gcc & native cc (hp, dec only) allowing
+          Detlefs & Zorn comparison study (in SIGPLAN Notices.)
+
+    Trial version Fri Aug 28 13:14:29 1992  Doug Lea  (dl at g.oswego.edu)
+      * Based loosely on libg++-1.2X malloc. (It retains some of the overall
+         structure of old version,  but most details differ.)
+
+*/
diff --git a/components/common/dlmalloc/malloc_wrapper.c b/components/common/dlmalloc/malloc_wrapper.c
new file mode 100644
index 0000000..f8afec2
--- /dev/null
+++ b/components/common/dlmalloc/malloc_wrapper.c
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include "compiler.h"
+#include <errno.h>
+#include <stddef.h> /* dlmalloc requires size_t */
+#include <stdint.h>
+#include <string.h>
+
+/* Allocating heap area */
+#ifndef SP_HEAP_SIZE
+#error "SP_HEAP_SIZE is undefined, please define it in the build system"
+#endif
+
+static uint8_t sp_heap[SP_HEAP_SIZE] __aligned(16);
+static uint8_t *program_break = sp_heap;
+
+/**
+ * Basic sbrk implementation which increases the program break through the
+ * sp_heap buffer.
+ */
+void *sbrk(ptrdiff_t incr)
+{
+	uint8_t *previous_break = program_break;
+	uint8_t *new_break = program_break + incr;
+
+	if ((new_break < sp_heap) || (new_break > (sp_heap + sizeof(sp_heap))))
+		return (void *)(uintptr_t) -1;
+
+	program_break += incr;
+
+	return (void *) previous_break;
+}
+
+
+
+/*
+ * There's no way of including a custom configuration file without modifying
+ * malloc.c. As a workaround this file includes the missing stddef.h, sets the
+ * configuration values of dlmalloc and then includes malloc.c.
+ */
+
+/* dlmalloc configuration */
+#define USE_SPIN_LOCKS	0
+#define HAVE_MORECORE	1
+#define HAVE_MMAP	0
+#define HAVE_MREMAP	0
+#define MALLOC_FAILURE_ACTION	do {} while (0)
+#define MMAP_CLEARS	0
+#define MORECORE_CONTIGUOUS	1
+#define MORECORE_CANNOT_TRIM	1
+#define LACKS_SYS_PARAM_H	1
+#define LACKS_SYS_TYPES_H	1
+#define LACKS_TIME_H	1
+#define LACKS_UNISTD_H	1
+#define NO_MALLINFO	1
+#define NO_MALLOC_STATS	1
+#define DEFAULT_GRANULARITY 64
+
+#include "malloc.c"
diff --git a/components/common/libc/CMakeLists.txt b/components/common/libc/CMakeLists.txt
new file mode 100644
index 0000000..3059c51
--- /dev/null
+++ b/components/common/libc/CMakeLists.txt
@@ -0,0 +1,57 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
+
+project(c LANGUAGES C)
+
+# Define our target
+add_library(c STATIC "")
+
+# Define include directories
+target_include_directories(c PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
+target_include_directories(c PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include/aarch64")
+
+include(${TS_ROOT}/tools/cmake/compiler/GCC.cmake)
+compiler_set_freestanding(TARGET c)
+
+# Add source files to be compiled.
+target_sources(c PRIVATE
+        "src/abort.c"
+        "src/assert.c"
+        "src/ctype.c"
+        "src/exit.c"
+        "src/memchr.c"
+        "src/memcmp.c"
+        "src/memcpy.c"
+        "src/memmove.c"
+        "src/memset.c"
+        "src/printf.c"
+        "src/putchar.c"
+        "src/puts.c"
+        "src/snprintf.c"
+        "src/strcpy.c"
+        "src/strlcat.c"
+        "src/strchr.c"
+        "src/strcmp.c"
+        "src/strlcpy.c"
+        "src/strlen.c"
+        "src/strncmp.c"
+        "src/strnlen.c"
+        "src/strrchr.c"
+        "src/strstr.c"
+        "src/strtok.c"
+        "src/strtol.c"
+        "src/strtok.c"
+        "src/strtoll.c"
+        "src/strtoul.c"
+        "src/strtoull.c"
+)
+
+target_compile_definitions(c INTERFACE ENABLE_CDEFSH_FIX)
+
+add_library(stdlib::c ALIAS c)
\ No newline at end of file
diff --git a/components/common/libc/component.cmake b/components/common/libc/component.cmake
deleted file mode 100644
index 042117b..0000000
--- a/components/common/libc/component.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-target_include_directories(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/include"
-)
diff --git a/components/common/libc/include/aarch32/endian_.h b/components/common/libc/include/aarch32/endian_.h
new file mode 100644
index 0000000..edca496
--- /dev/null
+++ b/components/common/libc/include/aarch32/endian_.h
@@ -0,0 +1,146 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2001 David E. O'Brien
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)endian.h	8.1 (Berkeley) 6/10/93
+ * $NetBSD: endian.h,v 1.7 1999/08/21 05:53:51 simonb Exp $
+ * $FreeBSD$
+ */
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef ENDIAN__H
+#define ENDIAN__H
+
+#include <stdint.h>
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define _LITTLE_ENDIAN  1234    /* LSB first: i386, vax */
+#define _BIG_ENDIAN     4321    /* MSB first: 68000, ibm, net */
+#define _PDP_ENDIAN     3412    /* LSB first in word, MSW first in long */
+
+#ifdef __ARMEB__
+#define _BYTE_ORDER	_BIG_ENDIAN
+#else
+#define	_BYTE_ORDER	_LITTLE_ENDIAN
+#endif /* __ARMEB__ */
+
+#if __BSD_VISIBLE
+#define LITTLE_ENDIAN   _LITTLE_ENDIAN
+#define BIG_ENDIAN      _BIG_ENDIAN
+#define PDP_ENDIAN      _PDP_ENDIAN
+#define BYTE_ORDER      _BYTE_ORDER
+#endif
+
+#ifdef __ARMEB__
+#define _QUAD_HIGHWORD 0
+#define _QUAD_LOWWORD 1
+#define __ntohl(x)	((uint32_t)(x))
+#define __ntohs(x)	((uint16_t)(x))
+#define __htonl(x)	((uint32_t)(x))
+#define __htons(x)	((uint16_t)(x))
+#else
+#define _QUAD_HIGHWORD  1
+#define _QUAD_LOWWORD 0
+#define __ntohl(x)        (__bswap32(x))
+#define __ntohs(x)        (__bswap16(x))
+#define __htonl(x)        (__bswap32(x))
+#define __htons(x)        (__bswap16(x))
+#endif /* __ARMEB__ */
+
+static __inline uint64_t
+__bswap64(uint64_t _x)
+{
+
+	return ((_x >> 56) | ((_x >> 40) & 0xff00) | ((_x >> 24) & 0xff0000) |
+	    ((_x >> 8) & 0xff000000) | ((_x << 8) & ((uint64_t)0xff << 32)) |
+	    ((_x << 24) & ((uint64_t)0xff << 40)) |
+	    ((_x << 40) & ((uint64_t)0xff << 48)) | ((_x << 56)));
+}
+
+static __inline uint32_t
+__bswap32_var(uint32_t v)
+{
+	uint32_t t1;
+
+	__asm __volatile("eor %1, %0, %0, ror #16\n"
+	    		"bic %1, %1, #0x00ff0000\n"
+			"mov %0, %0, ror #8\n"
+			"eor %0, %0, %1, lsr #8\n"
+			 : "+r" (v), "=r" (t1));
+
+	return (v);
+}
+
+static __inline uint16_t
+__bswap16_var(uint16_t v)
+{
+	uint32_t ret = v & 0xffff;
+
+	__asm __volatile(
+	    "mov    %0, %0, ror #8\n"
+	    "orr    %0, %0, %0, lsr #16\n"
+	    "bic    %0, %0, %0, lsl #16"
+	    : "+r" (ret));
+
+	return ((uint16_t)ret);
+}
+
+#ifdef __OPTIMIZE__
+
+#define __bswap32_constant(x)	\
+    ((((x) & 0xff000000U) >> 24) |	\
+     (((x) & 0x00ff0000U) >>  8) |	\
+     (((x) & 0x0000ff00U) <<  8) |	\
+     (((x) & 0x000000ffU) << 24))
+
+#define __bswap16_constant(x)	\
+    ((((x) & 0xff00) >> 8) |		\
+     (((x) & 0x00ff) << 8))
+
+#define __bswap16(x)	\
+    ((uint16_t)(__builtin_constant_p(x) ?	\
+     __bswap16_constant(x) :			\
+     __bswap16_var(x)))
+
+#define __bswap32(x)	\
+    ((uint32_t)(__builtin_constant_p(x) ? 	\
+     __bswap32_constant(x) :			\
+     __bswap32_var(x)))
+
+#else
+#define __bswap16(x)	__bswap16_var(x)
+#define __bswap32(x)	__bswap32_var(x)
+
+#endif /* __OPTIMIZE__ */
+#endif /* ENDIAN__H */
diff --git a/components/common/libc/include/aarch32/float.h b/components/common/libc/include/aarch32/float.h
new file mode 100644
index 0000000..857d76e
--- /dev/null
+++ b/components/common/libc/include/aarch32/float.h
@@ -0,0 +1,100 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)float.h	7.1 (Berkeley) 5/8/90
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_FLOAT_H_
+#define _MACHINE_FLOAT_H_ 1
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int __flt_rounds(void);
+__END_DECLS
+
+#define FLT_RADIX	2		/* b */
+#ifndef	_ARM_HARD_FLOAT
+#define	FLT_ROUNDS	__flt_rounds()
+#else
+#define	FLT_ROUNDS	(-1)
+#endif
+#if __ISO_C_VISIBLE >= 1999
+#define	FLT_EVAL_METHOD	0
+#define	DECIMAL_DIG	17		/* max precision in decimal digits */
+#endif
+
+#define FLT_MANT_DIG	24		/* p */
+#define FLT_EPSILON	1.19209290E-07F	/* b**(1-p) */
+#define FLT_DIG		6		/* floor((p-1)*log10(b))+(b == 10) */
+#define FLT_MIN_EXP	(-125)		/* emin */
+#define FLT_MIN		1.17549435E-38F	/* b**(emin-1) */
+#define FLT_MIN_10_EXP	(-37)		/* ceil(log10(b**(emin-1))) */
+#define FLT_MAX_EXP	128		/* emax */
+#define FLT_MAX		3.40282347E+38F	/* (1-b**(-p))*b**emax */
+#define FLT_MAX_10_EXP	38		/* floor(log10((1-b**(-p))*b**emax)) */
+#if __ISO_C_VISIBLE >= 2011
+#define	FLT_TRUE_MIN	1.40129846E-45F	/* b**(emin-p) */
+#define	FLT_DECIMAL_DIG	9		/* ceil(1+p*log10(b)) */
+#define	FLT_HAS_SUBNORM	1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#define DBL_MANT_DIG	53
+#define DBL_EPSILON	2.2204460492503131E-16
+#define DBL_DIG		15
+#define DBL_MIN_EXP	(-1021)
+#define DBL_MIN		2.2250738585072014E-308
+#define DBL_MIN_10_EXP	(-307)
+#define DBL_MAX_EXP	1024
+#define DBL_MAX		1.7976931348623157E+308
+#define DBL_MAX_10_EXP	308
+#if __ISO_C_VISIBLE >= 2011
+#define	DBL_TRUE_MIN	4.9406564584124654E-324
+#define	DBL_DECIMAL_DIG	17
+#define	DBL_HAS_SUBNORM	1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#define LDBL_MANT_DIG	DBL_MANT_DIG
+#define LDBL_EPSILON	((long double)DBL_EPSILON)
+#define LDBL_DIG	DBL_DIG
+#define LDBL_MIN_EXP	DBL_MIN_EXP
+#define LDBL_MIN	((long double)DBL_MIN)
+#define LDBL_MIN_10_EXP	DBL_MIN_10_EXP
+#define LDBL_MAX_EXP	DBL_MAX_EXP
+#define LDBL_MAX	((long double)DBL_MAX)
+#define LDBL_MAX_10_EXP	DBL_MAX_10_EXP
+#if __ISO_C_VISIBLE >= 2011
+#define	LDBL_TRUE_MIN	((long double)DBL_TRUE_MIN)
+#define	LDBL_DECIMAL_DIG DBL_DECIMAL_DIG
+#define	LDBL_HAS_SUBNORM DBL_HAS_SUBNORM
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#endif /* _MACHINE_FLOAT_H_ */
diff --git a/components/common/libc/include/aarch32/inttypes_.h b/components/common/libc/include/aarch32/inttypes_.h
new file mode 100644
index 0000000..0888bf0
--- /dev/null
+++ b/components/common/libc/include/aarch32/inttypes_.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef INTTYPES__H
+#define INTTYPES__H
+
+#define PRId64		"lld"	/* int64_t */
+#define PRIi64		"lli"	/* int64_t */
+#define PRIo64		"llo"	/* int64_t */
+#define PRIu64		"llu"	/* uint64_t */
+#define PRIx64		"llx"	/* uint64_t */
+#define PRIX64		"llX"	/* uint64_t */
+
+#define PRIdPTR         "d"     /* intptr_t */
+#define PRIiPTR         "i"     /* intptr_t */
+#define PRIoPTR         "o"     /* intptr_t */
+#define PRIuPTR         "u"     /* uintptr_t */
+#define PRIxPTR         "x"     /* uintptr_t */
+#define PRIXPTR         "X"     /* uintptr_t */
+
+#endif /* INTTYPES__H */
diff --git a/components/common/libc/include/aarch32/limits_.h b/components/common/libc/include/aarch32/limits_.h
new file mode 100644
index 0000000..5b0516a
--- /dev/null
+++ b/components/common/libc/include/aarch32/limits_.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define SCHAR_MAX  0x7F
+#define SCHAR_MIN  (-SCHAR_MAX - 1)
+#define CHAR_MAX   0x7F
+#define CHAR_MIN   (-CHAR_MAX - 1)
+#define UCHAR_MAX  0xFFU
+#define SHRT_MAX   0x7FFF
+#define SHRT_MIN   (-SHRT_MAX - 1)
+#define USHRT_MAX  0xFFFFU
+#define INT_MAX    0x7FFFFFFF
+#define INT_MIN    (-INT_MAX - 1)
+#define UINT_MAX   0xFFFFFFFFU
+#define LONG_MAX   0x7FFFFFFFL
+#define LONG_MIN   (-LONG_MAX - 1L)
+#define ULONG_MAX  0xFFFFFFFFUL
+#define LLONG_MAX  0x7FFFFFFFFFFFFFFFLL
+#define LLONG_MIN  (-LLONG_MAX - 1LL)
+#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL
+
+#define __LONG_BIT 32
+#define __WORD_BIT 32
diff --git a/components/common/libc/include/aarch32/stddef_.h b/components/common/libc/include/aarch32/stddef_.h
new file mode 100644
index 0000000..14ed094
--- /dev/null
+++ b/components/common/libc/include/aarch32/stddef_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STDDEF__H
+#define STDDEF__H
+
+#ifndef SIZET_
+typedef unsigned int size_t;
+#define SIZET_
+#endif
+
+#endif /* STDDEF__H */
diff --git a/components/common/libc/include/aarch32/stdint_.h b/components/common/libc/include/aarch32/stdint_.h
new file mode 100644
index 0000000..6e2deed
--- /dev/null
+++ b/components/common/libc/include/aarch32/stdint_.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDINT__H
+#define STDINT__H
+
+#define INT64_MAX  LLONG_MAX
+#define INT64_MIN  LLONG_MIN
+#define UINT64_MAX ULLONG_MAX
+
+#define INT64_C(x) x ## LL
+#define UINT64_C(x) x ## ULL
+
+typedef long long int64_t;
+typedef unsigned long long uint64_t;
+typedef long long int64_least_t;
+typedef unsigned long long uint64_least_t;
+typedef long long int64_fast_t;
+typedef unsigned long long uint64_fast_t;
+
+#endif
diff --git a/components/common/libc/include/aarch32/stdio_.h b/components/common/libc/include/aarch32/stdio_.h
new file mode 100644
index 0000000..7042664
--- /dev/null
+++ b/components/common/libc/include/aarch32/stdio_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STDIO__H
+#define STDIO__H
+
+#ifndef SSIZET_
+typedef int ssize_t;
+#define SSIZET_
+#endif
+
+#endif /* STDIO__H */
diff --git a/components/common/libc/include/aarch64/endian_.h b/components/common/libc/include/aarch64/endian_.h
new file mode 100644
index 0000000..58273d7
--- /dev/null
+++ b/components/common/libc/include/aarch64/endian_.h
@@ -0,0 +1,128 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2001 David E. O'Brien
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)endian.h	8.1 (Berkeley) 6/10/93
+ * $NetBSD: endian.h,v 1.7 1999/08/21 05:53:51 simonb Exp $
+ * $FreeBSD$
+ */
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef ENDIAN__H
+#define ENDIAN__H
+
+#include <stdint.h>
+
+/*
+ * Definitions for byte order, according to byte significance from low
+ * address to high.
+ */
+#define	_LITTLE_ENDIAN  1234    /* LSB first: i386, vax */
+#define	_BIG_ENDIAN     4321    /* MSB first: 68000, ibm, net */
+#define	_PDP_ENDIAN     3412    /* LSB first in word, MSW first in long */
+
+#define	_BYTE_ORDER	_LITTLE_ENDIAN
+
+#if __BSD_VISIBLE
+#define	LITTLE_ENDIAN   _LITTLE_ENDIAN
+#define	BIG_ENDIAN      _BIG_ENDIAN
+#define	PDP_ENDIAN      _PDP_ENDIAN
+#define	BYTE_ORDER      _BYTE_ORDER
+#endif
+
+#define	_QUAD_HIGHWORD  1
+#define	_QUAD_LOWWORD 0
+#define	__ntohl(x)        (__bswap32(x))
+#define	__ntohs(x)        (__bswap16(x))
+#define	__htonl(x)        (__bswap32(x))
+#define	__htons(x)        (__bswap16(x))
+
+static __inline uint64_t
+__bswap64(uint64_t x)
+{
+	uint64_t ret;
+
+	__asm __volatile("rev %0, %1\n"
+			 : "=&r" (ret), "+r" (x));
+
+	return (ret);
+}
+
+static __inline uint32_t
+__bswap32_var(uint32_t v)
+{
+	uint32_t ret;
+
+	__asm __volatile("rev32 %x0, %x1\n"
+			 : "=&r" (ret), "+r" (v));
+
+	return (ret);
+}
+
+static __inline uint16_t
+__bswap16_var(uint16_t v)
+{
+	uint32_t ret;
+
+	__asm __volatile("rev16 %w0, %w1\n"
+			 : "=&r" (ret), "+r" (v));
+
+	return ((uint16_t)ret);
+}
+
+#ifdef __OPTIMIZE__
+
+#define	__bswap32_constant(x)	\
+    ((((x) & 0xff000000U) >> 24) |	\
+     (((x) & 0x00ff0000U) >>  8) |	\
+     (((x) & 0x0000ff00U) <<  8) |	\
+     (((x) & 0x000000ffU) << 24))
+
+#define	__bswap16_constant(x)	\
+    ((((x) & 0xff00) >> 8) |		\
+     (((x) & 0x00ff) << 8))
+
+#define	__bswap16(x)	\
+    ((uint16_t)(__builtin_constant_p(x) ?	\
+     __bswap16_constant((uint16_t)(x)) :	\
+     __bswap16_var(x)))
+
+#define	__bswap32(x)	\
+    ((uint32_t)(__builtin_constant_p(x) ? 	\
+     __bswap32_constant((uint32_t)(x)) :	\
+     __bswap32_var(x)))
+
+#else
+#define	__bswap16(x)	__bswap16_var(x)
+#define	__bswap32(x)	__bswap32_var(x)
+
+#endif /* __OPTIMIZE__ */
+#endif /* ENDIAN__H */
diff --git a/components/common/libc/include/aarch64/float.h b/components/common/libc/include/aarch64/float.h
new file mode 100644
index 0000000..0829f6f
--- /dev/null
+++ b/components/common/libc/include/aarch64/float.h
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 1989 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from: @(#)float.h	7.1 (Berkeley) 5/8/90
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_FLOAT_H_
+#define	_MACHINE_FLOAT_H_
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int __flt_rounds(void);
+__END_DECLS
+
+#define	FLT_RADIX	2		/* b */
+#define	FLT_ROUNDS	__flt_rounds()
+#if __ISO_C_VISIBLE >= 1999
+#define	FLT_EVAL_METHOD	0
+#define	DECIMAL_DIG	17		/* max precision in decimal digits */
+#endif
+
+#define	FLT_MANT_DIG	24		/* p */
+#define	FLT_EPSILON	1.19209290E-07F	/* b**(1-p) */
+#define	FLT_DIG		6		/* floor((p-1)*log10(b))+(b == 10) */
+#define	FLT_MIN_EXP	(-125)		/* emin */
+#define	FLT_MIN		1.17549435E-38F	/* b**(emin-1) */
+#define	FLT_MIN_10_EXP	(-37)		/* ceil(log10(b**(emin-1))) */
+#define	FLT_MAX_EXP	128		/* emax */
+#define	FLT_MAX		3.40282347E+38F	/* (1-b**(-p))*b**emax */
+#define	FLT_MAX_10_EXP	38		/* floor(log10((1-b**(-p))*b**emax)) */
+#if __ISO_C_VISIBLE >= 2011
+#define	FLT_TRUE_MIN	1.40129846E-45F	/* b**(emin-p) */
+#define	FLT_DECIMAL_DIG	9		/* ceil(1+p*log10(b)) */
+#define	FLT_HAS_SUBNORM	1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#define	DBL_MANT_DIG	53
+#define	DBL_EPSILON	2.2204460492503131E-16
+#define	DBL_DIG		15
+#define	DBL_MIN_EXP	(-1021)
+#define	DBL_MIN		2.2250738585072014E-308
+#define	DBL_MIN_10_EXP	(-307)
+#define	DBL_MAX_EXP	1024
+#define	DBL_MAX		1.7976931348623157E+308
+#define	DBL_MAX_10_EXP	308
+#if __ISO_C_VISIBLE >= 2011
+#define	DBL_TRUE_MIN	4.9406564584124654E-324
+#define	DBL_DECIMAL_DIG	17
+#define	DBL_HAS_SUBNORM	1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#define	LDBL_MANT_DIG	113
+#define	LDBL_EPSILON	1.925929944387235853055977942584927319E-34L
+#define	LDBL_DIG	33
+#define	LDBL_MIN_EXP	(-16381)
+#define	LDBL_MIN	3.362103143112093506262677817321752603E-4932L
+#define	LDBL_MIN_10_EXP	(-4931)
+#define	LDBL_MAX_EXP	(+16384)
+#define	LDBL_MAX	1.189731495357231765085759326628007016E+4932L
+#define	LDBL_MAX_10_EXP	(+4932)
+#if __ISO_C_VISIBLE >= 2011
+#define	LDBL_TRUE_MIN	6.475175119438025110924438958227646552E-4966L
+#define	LDBL_DECIMAL_DIG 36
+#define	LDBL_HAS_SUBNORM 1
+#endif /* __ISO_C_VISIBLE >= 2011 */
+
+#endif /* _MACHINE_FLOAT_H_ */
diff --git a/components/common/libc/include/aarch64/inttypes_.h b/components/common/libc/include/aarch64/inttypes_.h
new file mode 100644
index 0000000..6109084
--- /dev/null
+++ b/components/common/libc/include/aarch64/inttypes_.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef INTTYPES__H
+#define INTTYPES__H
+
+#define PRId64		"ld"	/* int64_t */
+#define PRIi64		"li"	/* int64_t */
+#define PRIo64		"lo"	/* int64_t */
+#define PRIu64		"lu"	/* uint64_t */
+#define PRIx64		"lx"	/* uint64_t */
+#define PRIX64		"lX"	/* uint64_t */
+
+#define PRIdPTR         "ld"    /* intptr_t */
+#define PRIiPTR         "li"    /* intptr_t */
+#define PRIoPTR         "lo"    /* intptr_t */
+#define PRIuPTR         "lu"    /* uintptr_t */
+#define PRIxPTR         "lx"    /* uintptr_t */
+#define PRIXPTR         "lX"    /* uintptr_t */
+
+#endif /* INTTYPES__H */
diff --git a/components/common/libc/include/aarch64/limits_.h b/components/common/libc/include/aarch64/limits_.h
new file mode 100644
index 0000000..834439e
--- /dev/null
+++ b/components/common/libc/include/aarch64/limits_.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2018-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#define SCHAR_MAX  0x7F
+#define SCHAR_MIN  (-SCHAR_MAX - 1)
+#define CHAR_MAX   0x7F
+#define CHAR_MIN   (-CHAR_MAX - 1)
+#define UCHAR_MAX  0xFFU
+#define SHRT_MAX   0x7FFF
+#define SHRT_MIN   (-SHRT_MAX - 1)
+#define USHRT_MAX  0xFFFFU
+#define INT_MAX    0x7FFFFFFF
+#define INT_MIN    (-INT_MAX - 1)
+#define UINT_MAX   0xFFFFFFFFU
+#define LONG_MAX   0x7FFFFFFFFFFFFFFFL
+#define LONG_MIN   (-LONG_MAX - 1L)
+#define ULONG_MAX  0xFFFFFFFFFFFFFFFFUL
+#define LLONG_MAX  0x7FFFFFFFFFFFFFFFLL
+#define LLONG_MIN  (-LLONG_MAX - 1LL)
+#define ULLONG_MAX 0xFFFFFFFFFFFFFFFFULL
+
+#define __LONG_BIT 64
+#define __WORD_BIT 32
diff --git a/components/common/libc/include/aarch64/setjmp_.h b/components/common/libc/include/aarch64/setjmp_.h
new file mode 100644
index 0000000..a7d0b5c
--- /dev/null
+++ b/components/common/libc/include/aarch64/setjmp_.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SETJMP__H
+#define SETJMP__H
+
+#define JMP_CTX_X19	0x0
+#define JMP_CTX_X21	0x10
+#define JMP_CTX_X23	0x20
+#define JMP_CTX_X25	0x30
+#define JMP_CTX_X27	0x40
+#define JMP_CTX_X29	0x50
+#define JMP_CTX_SP	0x60
+#define JMP_CTX_END	0x70 /* Aligned to 16 bytes */
+
+#define JMP_SIZE	(JMP_CTX_END >> 3)
+
+#ifndef __ASSEMBLER__
+
+#include <cdefs.h>
+
+/* Jump buffer hosting x18 - x30 and sp_el0 registers */
+typedef uint64_t jmp_buf[JMP_SIZE] __aligned(16);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* SETJMP__H */
diff --git a/components/common/libc/include/aarch64/stddef_.h b/components/common/libc/include/aarch64/stddef_.h
new file mode 100644
index 0000000..963048e
--- /dev/null
+++ b/components/common/libc/include/aarch64/stddef_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STDDEF__H
+#define STDDEF__H
+
+#ifndef SIZET_
+typedef unsigned long size_t;
+#define SIZET_
+#endif
+
+#endif /* STDDEF__H */
diff --git a/components/common/libc/include/aarch64/stdint_.h b/components/common/libc/include/aarch64/stdint_.h
new file mode 100644
index 0000000..9e90798
--- /dev/null
+++ b/components/common/libc/include/aarch64/stdint_.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020-2024, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDINT__H
+#define STDINT__H
+
+#define INT64_MAX  LONG_MAX
+#define INT64_MIN  LONG_MIN
+#define UINT64_MAX ULONG_MAX
+
+#define INT64_C(x) x ## L
+#define UINT64_C(x) x ## UL
+
+typedef long int64_t;
+typedef unsigned long uint64_t;
+typedef long int64_least_t;
+typedef unsigned long uint64_least_t;
+typedef long int64_fast_t;
+typedef unsigned long uint64_fast_t;
+
+#endif
diff --git a/components/common/libc/include/aarch64/stdio_.h b/components/common/libc/include/aarch64/stdio_.h
new file mode 100644
index 0000000..331bcaa
--- /dev/null
+++ b/components/common/libc/include/aarch64/stdio_.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STDIO__H
+#define STDIO__H
+
+#ifndef SSIZET_
+typedef long ssize_t;
+#define SSIZET_
+#endif
+
+#endif /* STDIO__H */
diff --git a/components/common/libc/include/arm_acle.h b/components/common/libc/include/arm_acle.h
new file mode 100644
index 0000000..d1bc0f9
--- /dev/null
+++ b/components/common/libc/include/arm_acle.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021 Arm Limited
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * The definitions below are a subset of what we would normally get by using
+ * the compiler's version of arm_acle.h. We can't use that directly because
+ * we specify -nostdinc in the Makefiles.
+ *
+ * We just define the functions we need so far.
+ */
+
+#ifndef ARM_ACLE_H
+#define ARM_ACLE_H
+
+#if !defined(__aarch64__) || defined(__clang__)
+#	define __crc32b __builtin_arm_crc32b
+#	define __crc32w __builtin_arm_crc32w
+#else
+#	define __crc32b __builtin_aarch64_crc32b
+#	define __crc32w __builtin_aarch64_crc32w
+#endif
+
+#endif	/* ARM_ACLE_H */
diff --git a/components/common/libc/include/assert.h b/components/common/libc/include/assert.h
new file mode 100644
index 0000000..6a886db
--- /dev/null
+++ b/components/common/libc/include/assert.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ASSERT_H
+#define ASSERT_H
+
+#include <cdefs.h>
+
+#ifndef NDEBUG
+void __dead2 __assert(const char *file, int line, const char *func, const char *assertion);
+
+#define assert(e)	((e) ? (void)0 : __assert(__FILE__, __LINE__, __func__, #e))
+#else
+#define assert(e)	((void)(e))
+#endif
+
+#endif /* ASSERT_H */
diff --git a/components/common/libc/include/assert_fail_handler.h b/components/common/libc/include/assert_fail_handler.h
deleted file mode 100644
index 7f36f25..0000000
--- a/components/common/libc/include/assert_fail_handler.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-/*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
- */
-
-#ifndef ASSERT_FAIL_HANDLER_H_
-#define ASSERT_FAIL_HANDLER_H_
-
-#include "compiler.h"
-
-/*
- * Generic assert fail handler function definition. Should be implemented by the environment.
- */
-void __noreturn assert_fail_handler(const char *file, int line,
-				    const char *func, const char *failedexpr);
-
-#endif /* ASSERT_FAIL_HANDLER_H_ */
diff --git a/components/common/libc/include/cdefs.h b/components/common/libc/include/cdefs.h
new file mode 100644
index 0000000..75e9bbb
--- /dev/null
+++ b/components/common/libc/include/cdefs.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CDEFS_H
+#define CDEFS_H
+
+#define __dead2		__attribute__((__noreturn__))
+#define __deprecated	__attribute__((__deprecated__))
+#define __packed	__attribute__((__packed__))
+#define __used		__attribute__((__used__))
+#define __unused	__attribute__((__unused__))
+#define __maybe_unused	__attribute__((__unused__))
+#define __aligned(x)	__attribute__((__aligned__(x)))
+#define __section(x)	__attribute__((__section__(x)))
+#define __fallthrough	__attribute__((__fallthrough__))
+#if RECLAIM_INIT_CODE
+/*
+ * Add each function to a section that is unique so the functions can still
+ * be garbage collected
+ */
+#define __init		__section(".text.init." __FILE__ "." __XSTRING(__LINE__))
+#else
+#define __init
+#endif
+
+#define __printflike(fmtarg, firstvararg) \
+		__attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+
+#define __STRING(x)	#x
+#define __XSTRING(x)	__STRING(x)
+
+#endif /* CDEFS_H */
diff --git a/components/common/libc/include/ctype.h b/components/common/libc/include/ctype.h
new file mode 100644
index 0000000..98189c0
--- /dev/null
+++ b/components/common/libc/include/ctype.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CTYPE_H
+#define CTYPE_H
+
+int isalnum(int c);
+int isalpha(int c);
+int iscntrl(int c);
+int isdigit(int c);
+int isgraph(int c);
+int islower(int c);
+int isprint(int c);
+int ispunct(int c);
+int isspace(int c);
+int isupper(int c);
+int isxdigit(int c);
+int tolower(int c);
+int toupper(int c);
+
+#endif /* CTYPE_H */
diff --git a/components/common/libc/include/endian.h b/components/common/libc/include/endian.h
new file mode 100644
index 0000000..9c9fd58
--- /dev/null
+++ b/components/common/libc/include/endian.h
@@ -0,0 +1,191 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef ENDIAN_H
+#define ENDIAN_H
+
+#include <cdefs.h>
+#include <stdint.h>
+#include <endian_.h>
+
+/*
+ * General byte order swapping functions.
+ */
+#define	bswap16(x)	__bswap16(x)
+#define	bswap32(x)	__bswap32(x)
+#define	bswap64(x)	__bswap64(x)
+
+/*
+ * Host to big endian, host to little endian, big endian to host, and little
+ * endian to host byte order functions as detailed in byteorder(9).
+ */
+#if _BYTE_ORDER == _LITTLE_ENDIAN
+#define	htobe16(x)	bswap16((x))
+#define	htobe32(x)	bswap32((x))
+#define	htobe64(x)	bswap64((x))
+#define	htole16(x)	((uint16_t)(x))
+#define	htole32(x)	((uint32_t)(x))
+#define	htole64(x)	((uint64_t)(x))
+
+#define	be16toh(x)	bswap16((x))
+#define	be32toh(x)	bswap32((x))
+#define	be64toh(x)	bswap64((x))
+#define	le16toh(x)	((uint16_t)(x))
+#define	le32toh(x)	((uint32_t)(x))
+#define	le64toh(x)	((uint64_t)(x))
+#else /* _BYTE_ORDER != _LITTLE_ENDIAN */
+#define	htobe16(x)	((uint16_t)(x))
+#define	htobe32(x)	((uint32_t)(x))
+#define	htobe64(x)	((uint64_t)(x))
+#define	htole16(x)	bswap16((x))
+#define	htole32(x)	bswap32((x))
+#define	htole64(x)	bswap64((x))
+
+#define	be16toh(x)	((uint16_t)(x))
+#define	be32toh(x)	((uint32_t)(x))
+#define	be64toh(x)	((uint64_t)(x))
+#define	le16toh(x)	bswap16((x))
+#define	le32toh(x)	bswap32((x))
+#define	le64toh(x)	bswap64((x))
+#endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
+
+/* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
+
+static __inline uint16_t
+be16dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return ((p[0] << 8) | p[1]);
+}
+
+static __inline uint32_t
+be32dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
+}
+
+static __inline uint64_t
+be64dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4));
+}
+
+static __inline uint16_t
+le16dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return ((p[1] << 8) | p[0]);
+}
+
+static __inline uint32_t
+le32dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
+}
+
+static __inline uint64_t
+le64dec(const void *pp)
+{
+	uint8_t const *p = (uint8_t const *)pp;
+
+	return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p));
+}
+
+static __inline void
+be16enc(void *pp, uint16_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	p[0] = (u >> 8) & 0xff;
+	p[1] = u & 0xff;
+}
+
+static __inline void
+be32enc(void *pp, uint32_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	p[0] = (u >> 24) & 0xff;
+	p[1] = (u >> 16) & 0xff;
+	p[2] = (u >> 8) & 0xff;
+	p[3] = u & 0xff;
+}
+
+static __inline void
+be64enc(void *pp, uint64_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	be32enc(p, (uint32_t)(u >> 32));
+	be32enc(p + 4, (uint32_t)(u & 0xffffffffU));
+}
+
+static __inline void
+le16enc(void *pp, uint16_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	p[0] = u & 0xff;
+	p[1] = (u >> 8) & 0xff;
+}
+
+static __inline void
+le32enc(void *pp, uint32_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	p[0] = u & 0xff;
+	p[1] = (u >> 8) & 0xff;
+	p[2] = (u >> 16) & 0xff;
+	p[3] = (u >> 24) & 0xff;
+}
+
+static __inline void
+le64enc(void *pp, uint64_t u)
+{
+	uint8_t *p = (uint8_t *)pp;
+
+	le32enc(p, (uint32_t)(u & 0xffffffffU));
+	le32enc(p + 4, (uint32_t)(u >> 32));
+}
+
+#endif /* ENDIAN_H */
diff --git a/components/common/libc/include/errno.h b/components/common/libc/include/errno.h
new file mode 100644
index 0000000..b536fe9
--- /dev/null
+++ b/components/common/libc/include/errno.h
@@ -0,0 +1,169 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ * (c) UNIX System Laboratories, Inc.
+ * All or some portions of this file are derived from material licensed
+ * to the University of California by American Telephone and Telegraph
+ * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * the permission of UNIX System Laboratories, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)errno.h	8.5 (Berkeley) 1/21/94
+ * $FreeBSD$
+ */
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef ERRNO_H
+#define ERRNO_H
+
+#define	EPERM		1		/* Operation not permitted */
+#define	ENOENT		2		/* No such file or directory */
+#define	ESRCH		3		/* No such process */
+#define	EINTR		4		/* Interrupted system call */
+#define	EIO		5		/* Input/output error */
+#define	ENXIO		6		/* Device not configured */
+#define	E2BIG		7		/* Argument list too long */
+#define	ENOEXEC		8		/* Exec format error */
+#define	EBADF		9		/* Bad file descriptor */
+#define	ECHILD		10		/* No child processes */
+#define	EDEADLK		11		/* Resource deadlock avoided */
+					/* 11 was EAGAIN */
+#define	ENOMEM		12		/* Cannot allocate memory */
+#define	EACCES		13		/* Permission denied */
+#define	EFAULT		14		/* Bad address */
+#define	ENOTBLK		15		/* Block device required */
+#define	EBUSY		16		/* Device busy */
+#define	EEXIST		17		/* File exists */
+#define	EXDEV		18		/* Cross-device link */
+#define	ENODEV		19		/* Operation not supported by device */
+#define	ENOTDIR		20		/* Not a directory */
+#define	EISDIR		21		/* Is a directory */
+#define	EINVAL		22		/* Invalid argument */
+#define	ENFILE		23		/* Too many open files in system */
+#define	EMFILE		24		/* Too many open files */
+#define	ENOTTY		25		/* Inappropriate ioctl for device */
+#define	ETXTBSY		26		/* Text file busy */
+#define	EFBIG		27		/* File too large */
+#define	ENOSPC		28		/* No space left on device */
+#define	ESPIPE		29		/* Illegal seek */
+#define	EROFS		30		/* Read-only filesystem */
+#define	EMLINK		31		/* Too many links */
+#define	EPIPE		32		/* Broken pipe */
+
+/* math software */
+#define	EDOM		33		/* Numerical argument out of domain */
+#define	ERANGE		34		/* Result too large */
+
+/* non-blocking and interrupt i/o */
+#define	EAGAIN		35		/* Resource temporarily unavailable */
+#define	EWOULDBLOCK	EAGAIN		/* Operation would block */
+#define	EINPROGRESS	36		/* Operation now in progress */
+#define	EALREADY	37		/* Operation already in progress */
+
+/* ipc/network software -- argument errors */
+#define	ENOTSOCK	38		/* Socket operation on non-socket */
+#define	EDESTADDRREQ	39		/* Destination address required */
+#define	EMSGSIZE	40		/* Message too long */
+#define	EPROTOTYPE	41		/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	42		/* Protocol not available */
+#define	EPROTONOSUPPORT	43		/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	44		/* Socket type not supported */
+#define	EOPNOTSUPP	45		/* Operation not supported */
+#define	ENOTSUP		EOPNOTSUPP	/* Operation not supported */
+#define	EPFNOSUPPORT	46		/* Protocol family not supported */
+#define	EAFNOSUPPORT	47		/* Address family not supported by protocol family */
+#define	EADDRINUSE	48		/* Address already in use */
+#define	EADDRNOTAVAIL	49		/* Can't assign requested address */
+
+/* ipc/network software -- operational errors */
+#define	ENETDOWN	50		/* Network is down */
+#define	ENETUNREACH	51		/* Network is unreachable */
+#define	ENETRESET	52		/* Network dropped connection on reset */
+#define	ECONNABORTED	53		/* Software caused connection abort */
+#define	ECONNRESET	54		/* Connection reset by peer */
+#define	ENOBUFS		55		/* No buffer space available */
+#define	EISCONN		56		/* Socket is already connected */
+#define	ENOTCONN	57		/* Socket is not connected */
+#define	ESHUTDOWN	58		/* Can't send after socket shutdown */
+#define	ETOOMANYREFS	59		/* Too many references: can't splice */
+#define	ETIMEDOUT	60		/* Operation timed out */
+#define	ECONNREFUSED	61		/* Connection refused */
+
+#define	ELOOP		62		/* Too many levels of symbolic links */
+#define	ENAMETOOLONG	63		/* File name too long */
+
+/* should be rearranged */
+#define	EHOSTDOWN	64		/* Host is down */
+#define	EHOSTUNREACH	65		/* No route to host */
+#define	ENOTEMPTY	66		/* Directory not empty */
+
+/* quotas & mush */
+#define	EPROCLIM	67		/* Too many processes */
+#define	EUSERS		68		/* Too many users */
+#define	EDQUOT		69		/* Disc quota exceeded */
+
+/* Network File System */
+#define	ESTALE		70		/* Stale NFS file handle */
+#define	EREMOTE		71		/* Too many levels of remote in path */
+#define	EBADRPC		72		/* RPC struct is bad */
+#define	ERPCMISMATCH	73		/* RPC version wrong */
+#define	EPROGUNAVAIL	74		/* RPC prog. not avail */
+#define	EPROGMISMATCH	75		/* Program version wrong */
+#define	EPROCUNAVAIL	76		/* Bad procedure for program */
+
+#define	ENOLCK		77		/* No locks available */
+#define	ENOSYS		78		/* Function not implemented */
+
+#define	EFTYPE		79		/* Inappropriate file type or format */
+#define	EAUTH		80		/* Authentication error */
+#define	ENEEDAUTH	81		/* Need authenticator */
+#define	EIDRM		82		/* Identifier removed */
+#define	ENOMSG		83		/* No message of desired type */
+#define	EOVERFLOW	84		/* Value too large to be stored in data type */
+#define	ECANCELED	85		/* Operation canceled */
+#define	EILSEQ		86		/* Illegal byte sequence */
+#define	ENOATTR		87		/* Attribute not found */
+
+#define	EDOOFUS		88		/* Programming error */
+
+#define	EBADMSG		89		/* Bad message */
+#define	EMULTIHOP	90		/* Multihop attempted */
+#define	ENOLINK		91		/* Link has been severed */
+#define	EPROTO		92		/* Protocol error */
+
+#define	ENOTCAPABLE	93		/* Capabilities insufficient */
+#define	ECAPMODE	94		/* Not permitted in capability mode */
+#define	ENOTRECOVERABLE	95		/* State not recoverable */
+#define	EOWNERDEAD	96		/* Previous owner died */
+
+#define	ELAST		96		/* Must be equal largest errno */
+
+#endif /* ERRNO_H */
diff --git a/components/common/libc/include/inttypes.h b/components/common/libc/include/inttypes.h
new file mode 100644
index 0000000..344b71c
--- /dev/null
+++ b/components/common/libc/include/inttypes.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2020 Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2020, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef INTTYPES_H
+#define INTTYPES_H
+
+#include <inttypes_.h>
+#include <stdint.h>
+
+#define PRId8		"d"	/* int8_t */
+#define PRId16		"d"	/* int16_t */
+#define PRId32		"d"	/* int32_t */
+
+#define PRIi8		"i"	/* int8_t */
+#define PRIi16		"i"	/* int16_t */
+#define PRIi32		"i"	/* int32_t */
+
+#define PRIo8		"o"	/* int8_t */
+#define PRIo16		"o"	/* int16_t */
+#define PRIo32		"o"	/* int32_t */
+
+#define PRIu8		"u"	/* uint8_t */
+#define PRIu16		"u"	/* uint16_t */
+#define PRIu32		"u"	/* uint32_t */
+
+#define PRIx8		"x"	/* uint8_t */
+#define PRIx16		"x"	/* uint16_t */
+#define PRIx32		"x"	/* uint32_t */
+
+#define PRIX8		"X"	/* uint8_t */
+#define PRIX16		"X"	/* uint16_t */
+#define PRIX32		"X"	/* uint32_t */
+
+#endif
diff --git a/components/common/libc/include/libc_init.h b/components/common/libc/include/libc_init.h
deleted file mode 100644
index 28988d5..0000000
--- a/components/common/libc/include/libc_init.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-/*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
- */
-
-#ifndef LIBC_INIT_H_
-#define LIBC_INIT_H_
-
-/*
- * Generic libc init function. Implemented by the newlib external, should be called by the
- * environment on boot.
- */
-void libc_init(void);
-
-#endif /* LIBC_INIT_H_ */
diff --git a/components/common/libc/include/libc_platform.h b/components/common/libc/include/libc_platform.h
new file mode 100644
index 0000000..77c5706
--- /dev/null
+++ b/components/common/libc/include/libc_platform.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+/*
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
+ */
+
+#ifndef LIBC_PLATFORM_H_
+#define LIBC_PLATFORM_H_
+
+#include <cdefs.h>
+
+/*
+ * Generic assert fail and abort handler function definitions.
+ * Should be implemented by the environment.
+ */
+void __dead2 platform_assert(const char *file, int line, const char *func,
+			     const char *failedexpr);
+
+void __dead2 platform_abort(void);
+
+#endif /* LIBC_PLATFORM_H_ */
diff --git a/components/common/libc/include/limits.h b/components/common/libc/include/limits.h
new file mode 100644
index 0000000..c5c8764
--- /dev/null
+++ b/components/common/libc/include/limits.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef LIMITS_H
+#define LIMITS_H
+
+#include <limits_.h>
+
+#define CHAR_BIT   8
+#define MB_LEN_MAX 1
+
+#endif /* LIMITS_H */
diff --git a/components/common/libc/include/malloc.h b/components/common/libc/include/malloc.h
new file mode 100644
index 0000000..275211d
--- /dev/null
+++ b/components/common/libc/include/malloc.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MEMORY_H
+#define MEMORY_H
+
+#include <stddef.h>
+
+/*
+ * The declaration of this function is part of libc but it is implemented in
+ * the allocator.
+ */
+void *memalign(size_t alignment, size_t size);
+
+#endif /* MEMORY_H */
\ No newline at end of file
diff --git a/components/common/libc/include/setjmp.h b/components/common/libc/include/setjmp.h
new file mode 100644
index 0000000..871c868
--- /dev/null
+++ b/components/common/libc/include/setjmp.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SETJMP_H
+#define SETJMP_H
+
+#include <setjmp_.h>
+
+#ifndef __ASSEMBLER__
+
+#include <cdefs.h>
+
+int setjmp(jmp_buf env);
+__dead2 void longjmp(jmp_buf env, int val);
+
+#endif /* __ASSEMBLER__ */
+#endif /* SETJMP_H */
diff --git a/components/common/libc/include/stdarg.h b/components/common/libc/include/stdarg.h
new file mode 100644
index 0000000..2d1f785
--- /dev/null
+++ b/components/common/libc/include/stdarg.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDARG_H
+#define STDARG_H
+
+#define va_list __builtin_va_list
+#define va_start(ap, last) __builtin_va_start(ap, last)
+#define va_end(ap) __builtin_va_end(ap)
+#define va_copy(to, from) __builtin_va_copy(to, from)
+#define va_arg(to, type) __builtin_va_arg(to, type)
+
+#endif /* STDARG_H */
diff --git a/components/common/libc/include/stdbool.h b/components/common/libc/include/stdbool.h
new file mode 100644
index 0000000..c2c9b22
--- /dev/null
+++ b/components/common/libc/include/stdbool.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STDBOOL_H
+#define STDBOOL_H
+
+#define bool	_Bool
+
+#define true	(0 < 1)
+#define false	(0 > 1)
+
+#define __bool_true_false_are_defined	1
+
+#endif /* STDBOOL_H */
diff --git a/components/common/libc/include/stddef.h b/components/common/libc/include/stddef.h
new file mode 100644
index 0000000..aaad673
--- /dev/null
+++ b/components/common/libc/include/stddef.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018-2019, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDDEF_H
+#define STDDEF_H
+
+#include <stddef_.h>
+
+#ifndef _PTRDIFF_T
+typedef long ptrdiff_t;
+#define _PTRDIFF_T
+#endif
+
+#ifndef NULL
+#define NULL ((void *) 0)
+#endif
+
+#define offsetof(st, m) __builtin_offsetof(st, m)
+
+#endif /* STDDEF_H */
diff --git a/components/common/libc/include/stdint.h b/components/common/libc/include/stdint.h
new file mode 100644
index 0000000..dd8ebba
--- /dev/null
+++ b/components/common/libc/include/stdint.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018-2024, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDINT_H
+#define STDINT_H
+
+#include <limits.h>
+#include <stdint_.h>
+
+#define INT8_MAX  CHAR_MAX
+#define INT8_MIN  CHAR_MIN
+#define UINT8_MAX UCHAR_MAX
+
+#define INT16_MAX  SHRT_MAX
+#define INT16_MIN  SHRT_MIN
+#define UINT16_MAX USHRT_MAX
+
+#define INT32_MAX  INT_MAX
+#define INT32_MIN  INT_MIN
+#define UINT32_MAX UINT_MAX
+
+#define INT_LEAST8_MIN  INT8_MIN
+#define INT_LEAST8_MAX  INT8_MAX
+#define UINT_LEAST8_MAX UINT8_MAX
+
+#define INT_LEAST16_MIN  INT16_MIN
+#define INT_LEAST16_MAX  INT16_MAX
+#define UINT_LEAST16_MAX UINT16_MAX
+
+#define INT_LEAST32_MIN  INT32_MIN
+#define INT_LEAST32_MAX  INT32_MAX
+#define UINT_LEAST32_MAX UINT32_MAX
+
+#define INT_LEAST64_MIN  INT64_MIN
+#define INT_LEAST64_MAX  INT64_MAX
+#define UINT_LEAST64_MAX UINT64_MAX
+
+#define INT_FAST8_MIN  INT32_MIN
+#define INT_FAST8_MAX  INT32_MAX
+#define UINT_FAST8_MAX UINT32_MAX
+
+#define INT_FAST16_MIN  INT32_MIN
+#define INT_FAST16_MAX  INT32_MAX
+#define UINT_FAST16_MAX UINT32_MAX
+
+#define INT_FAST32_MIN  INT32_MIN
+#define INT_FAST32_MAX  INT32_MAX
+#define UINT_FAST32_MAX UINT32_MAX
+
+#define INT_FAST64_MIN  INT64_MIN
+#define INT_FAST64_MAX  INT64_MAX
+#define UINT_FAST64_MAX UINT64_MAX
+
+#define INTPTR_MIN  LONG_MIN
+#define INTPTR_MAX  LONG_MAX
+#define UINTPTR_MAX ULONG_MAX
+
+#define INTMAX_MIN  LLONG_MIN
+#define INTMAX_MAX  LLONG_MAX
+#define UINTMAX_MAX ULLONG_MAX
+
+#define PTRDIFF_MIN LONG_MIN
+#define PTRDIFF_MAX LONG_MAX
+
+#define SIZE_MAX ULONG_MAX
+
+#define INT8_C(x)  x
+#define INT16_C(x) x
+#define INT32_C(x) x
+
+#define UINT8_C(x)  x
+#define UINT16_C(x) x
+#define UINT32_C(x) x ## U
+
+#define INTMAX_C(x)  x ## LL
+#define UINTMAX_C(x) x ## ULL
+
+typedef signed char int8_t;
+typedef short int16_t;
+typedef int int32_t;
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+
+typedef signed char int_least8_t;
+typedef short int_least16_t;
+typedef int int_least32_t;
+
+typedef unsigned char uint_least8_t;
+typedef unsigned short uint_least16_t;
+typedef unsigned int uint_least32_t;
+
+typedef int int_fast8_t;
+typedef int int_fast16_t;
+typedef int int_fast32_t;
+
+typedef unsigned int uint_fast8_t;
+typedef unsigned int uint_fast16_t;
+typedef unsigned int uint_fast32_t;
+
+typedef long intptr_t;
+typedef unsigned long uintptr_t;
+
+/*
+* Conceptually, these are supposed to be the largest integers representable in C,
+* but GCC and Clang define them as long long for compatibility.
+*/
+typedef long long intmax_t;
+typedef unsigned long long uintmax_t;
+
+typedef long register_t;
+typedef unsigned long u_register_t;
+
+#endif /* STDINT_H */
diff --git a/components/common/libc/include/stdio.h b/components/common/libc/include/stdio.h
new file mode 100644
index 0000000..5ceaf68
--- /dev/null
+++ b/components/common/libc/include/stdio.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018-2019, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDIO_H
+#define STDIO_H
+
+#include <cdefs.h>
+#include <stddef.h>
+#include <stdio_.h>
+
+#define EOF            -1
+
+int printf(const char *fmt, ...) __printflike(1, 2);
+int snprintf(char *s, size_t n, const char *fmt, ...) __printflike(3, 4);
+
+#ifdef STDARG_H
+int vprintf(const char *fmt, va_list args);
+int vsnprintf(char *s, size_t n, const char *fmt, va_list args);
+#endif
+
+int putchar(int c);
+int puts(const char *s);
+
+#endif /* STDIO_H */
diff --git a/components/common/libc/include/stdlib.h b/components/common/libc/include/stdlib.h
new file mode 100644
index 0000000..219a333
--- /dev/null
+++ b/components/common/libc/include/stdlib.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012-2021 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018-2024, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef STDLIB_H
+#define STDLIB_H
+
+#include <stddef.h>
+
+#define EXIT_FAILURE 1
+#define EXIT_SUCCESS 0
+
+#define _ATEXIT_MAX 1
+
+#define isspace(x)    (((x) == ' ') || ((x) == '\r') || ((x) == '\n') || \
+			((x) == '\t') || ((x) == '\b'))
+
+extern void abort(void);
+extern int atexit(void (*func)(void));
+extern void exit(int status);
+
+long strtol(const char *nptr, char **endptr, int base);
+unsigned long strtoul(const char *nptr, char **endptr, int base);
+long long strtoll(const char *nptr, char **endptr, int base);
+unsigned long long strtoull(const char *nptr, char **endptr, int base);
+
+/*
+ * The declaration of these functions is part of libc but they are implemented
+ * in the allocator.
+ */
+void *malloc(size_t size);
+void free(void *ptr);
+void *calloc(size_t nmemb, size_t size);
+void *realloc(void *ptr, size_t size);
+
+#endif /* STDLIB_H */
diff --git a/components/common/libc/include/string.h b/components/common/libc/include/string.h
new file mode 100644
index 0000000..135e443
--- /dev/null
+++ b/components/common/libc/include/string.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018-2024, Arm Limited and Contributors.
+ * Portions copyright (c) 2023, Intel Corporation. All rights reserved.
+ * All rights reserved.
+ */
+
+#ifndef STRING_H
+#define STRING_H
+
+#include <stddef.h>
+
+void *memcpy(void *dst, const void *src, size_t len);
+int memcpy_s(void *dst, size_t dsize, void *src, size_t ssize);
+void *memmove(void *dst, const void *src, size_t len);
+int memcmp(const void *s1, const void *s2, size_t len);
+int strcmp(const char *s1, const char *s2);
+int strncmp(const char *s1, const char *s2, size_t n);
+void *memchr(const void *src, int c, size_t len);
+void *memrchr(const void *src, int c, size_t len);
+char *strchr(const char *s, int c);
+void *memset(void *dst, int val, size_t count);
+size_t strlen(const char *s);
+size_t strnlen(const char *s, size_t maxlen);
+char *strrchr(const char *p, int ch);
+size_t strlcpy(char * dst, const char * src, size_t dsize);
+size_t strlcat(char * dst, const char * src, size_t dsize);
+char *strtok_r(char *s, const char *delim, char **last);
+char *strstr(const char *haystack, const char *needle);
+
+#endif /* STRING_H */
diff --git a/components/common/libc/include/sys/cdefs.h b/components/common/libc/include/sys/cdefs.h
new file mode 100644
index 0000000..1ace5fb
--- /dev/null
+++ b/components/common/libc/include/sys/cdefs.h
@@ -0,0 +1,922 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Berkeley Software Design, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)cdefs.h	8.8 (Berkeley) 1/9/95
+ * $FreeBSD$
+ */
+
+#ifndef	_SYS_CDEFS_H_
+#define	_SYS_CDEFS_H_
+
+#if defined(_KERNEL) && defined(_STANDALONE)
+#error "_KERNEL and _STANDALONE are mutually exclusive"
+#endif
+
+/*
+ * Testing against Clang-specific extensions.
+ */
+#ifndef	__has_attribute
+#define	__has_attribute(x)	0
+#endif
+#ifndef	__has_extension
+#define	__has_extension		__has_feature
+#endif
+#ifndef	__has_feature
+#define	__has_feature(x)	0
+#endif
+#ifndef	__has_include
+#define	__has_include(x)	0
+#endif
+#ifndef	__has_builtin
+#define	__has_builtin(x)	0
+#endif
+
+#if defined(__cplusplus)
+#define	__BEGIN_DECLS	extern "C" {
+#define	__END_DECLS	}
+#else
+#define	__BEGIN_DECLS
+#define	__END_DECLS
+#endif
+
+/*
+ * This code has been put in place to help reduce the addition of
+ * compiler specific defines in FreeBSD code.  It helps to aid in
+ * having a compiler-agnostic source tree.
+ */
+
+#if defined(__GNUC__)
+
+#if __GNUC__ >= 3
+#define	__GNUCLIKE_ASM 3
+#define	__GNUCLIKE_MATH_BUILTIN_CONSTANTS
+#else
+#define	__GNUCLIKE_ASM 2
+#endif
+#define	__GNUCLIKE___TYPEOF 1
+#define	__GNUCLIKE___SECTION 1
+
+#define	__GNUCLIKE_CTOR_SECTION_HANDLING 1
+
+#define	__GNUCLIKE_BUILTIN_CONSTANT_P 1
+
+#if (__GNUC_MINOR__ > 95 || __GNUC__ >= 3)
+#define	__GNUCLIKE_BUILTIN_VARARGS 1
+#define	__GNUCLIKE_BUILTIN_STDARG 1
+#define	__GNUCLIKE_BUILTIN_VAALIST 1
+#endif
+
+#define	__GNUC_VA_LIST_COMPATIBILITY 1
+
+/*
+ * Compiler memory barriers, specific to gcc and clang.
+ */
+#define	__compiler_membar()	__asm __volatile(" " : : : "memory")
+
+#define	__GNUCLIKE_BUILTIN_NEXT_ARG 1
+#define	__GNUCLIKE_MATH_BUILTIN_RELOPS
+
+#define	__GNUCLIKE_BUILTIN_MEMCPY 1
+
+/* XXX: if __GNUC__ >= 2: not tested everywhere originally, where replaced */
+#define	__CC_SUPPORTS_INLINE 1
+#define	__CC_SUPPORTS___INLINE 1
+#define	__CC_SUPPORTS___INLINE__ 1
+
+#define	__CC_SUPPORTS___FUNC__ 1
+#define	__CC_SUPPORTS_WARNING 1
+
+#define	__CC_SUPPORTS_VARADIC_XXX 1 /* see varargs.h */
+
+#define	__CC_SUPPORTS_DYNAMIC_ARRAY_INIT 1
+
+#endif /* __GNUC__ */
+
+/*
+ * Macro to test if we're using a specific version of gcc or later.
+ */
+#if defined(__GNUC__)
+#define	__GNUC_PREREQ__(ma, mi)	\
+	(__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
+#else
+#define	__GNUC_PREREQ__(ma, mi)	0
+#endif
+
+/*
+ * The __CONCAT macro is used to concatenate parts of symbol names, e.g.
+ * with "#define OLD(foo) __CONCAT(old,foo)", OLD(foo) produces oldfoo.
+ * The __CONCAT macro is a bit tricky to use if it must work in non-ANSI
+ * mode -- there must be no spaces between its arguments, and for nested
+ * __CONCAT's, all the __CONCAT's must be at the left.  __CONCAT can also
+ * concatenate double-quoted strings produced by the __STRING macro, but
+ * this only works with ANSI C.
+ *
+ * __XSTRING is like __STRING, but it expands any macros in its argument
+ * first.  It is only available with ANSI C.
+ */
+#if defined(__STDC__) || defined(__cplusplus)
+#define	__P(protos)	protos		/* full-blown ANSI C */
+#define	__CONCAT1(x,y)	x ## y
+#define	__CONCAT(x,y)	__CONCAT1(x,y)
+#define	__STRING(x)	#x		/* stringify without expanding x */
+#define	__XSTRING(x)	__STRING(x)	/* expand x, then stringify */
+
+#define	__const		const		/* define reserved names to standard */
+#define	__signed	signed
+#define	__volatile	volatile
+#if defined(__cplusplus)
+#define	__inline	inline		/* convert to C++ keyword */
+#else
+#if !(defined(__CC_SUPPORTS___INLINE))
+#define	__inline			/* delete GCC keyword */
+#endif /* ! __CC_SUPPORTS___INLINE */
+#endif /* !__cplusplus */
+
+#else	/* !(__STDC__ || __cplusplus) */
+#define	__P(protos)	()		/* traditional C preprocessor */
+#define	__CONCAT(x,y)	x/**/y
+#define	__STRING(x)	"x"
+
+#if !defined(__CC_SUPPORTS___INLINE)
+#define	__const				/* delete pseudo-ANSI C keywords */
+#define	__inline
+#define	__signed
+#define	__volatile
+/*
+ * In non-ANSI C environments, new programs will want ANSI-only C keywords
+ * deleted from the program and old programs will want them left alone.
+ * When using a compiler other than gcc, programs using the ANSI C keywords
+ * const, inline etc. as normal identifiers should define -DNO_ANSI_KEYWORDS.
+ * When using "gcc -traditional", we assume that this is the intent; if
+ * __GNUC__ is defined but __STDC__ is not, we leave the new keywords alone.
+ */
+#ifndef	NO_ANSI_KEYWORDS
+#define	const				/* delete ANSI C keywords */
+#define	inline
+#define	signed
+#define	volatile
+#endif	/* !NO_ANSI_KEYWORDS */
+#endif	/* !__CC_SUPPORTS___INLINE */
+#endif	/* !(__STDC__ || __cplusplus) */
+
+/*
+ * Compiler-dependent macros to help declare dead (non-returning) and
+ * pure (no side effects) functions, and unused variables.  They are
+ * null except for versions of gcc that are known to support the features
+ * properly (old versions of gcc-2 supported the dead and pure features
+ * in a different (wrong) way).  If we do not provide an implementation
+ * for a given compiler, let the compile fail if it is told to use
+ * a feature that we cannot live without.
+ */
+#define	__weak_symbol	__attribute__((__weak__))
+#if !__GNUC_PREREQ__(2, 5)
+#define	__dead2
+#define	__pure2
+#define	__unused
+#endif
+#if __GNUC__ == 2 && __GNUC_MINOR__ >= 5 && __GNUC_MINOR__ < 7
+#define	__dead2		__attribute__((__noreturn__))
+#define	__pure2		__attribute__((__const__))
+#define	__unused
+/* XXX Find out what to do for __packed, __aligned and __section */
+#endif
+#if __GNUC_PREREQ__(2, 7)
+#define	__dead2		__attribute__((__noreturn__))
+#define	__pure2		__attribute__((__const__))
+#define	__unused	__attribute__((__unused__))
+#define	__used		__attribute__((__used__))
+#define	__packed	__attribute__((__packed__))
+#define	__aligned(x)	__attribute__((__aligned__(x)))
+#define	__section(x)	__attribute__((__section__(x)))
+#endif
+#if __GNUC_PREREQ__(4, 3) || __has_attribute(__alloc_size__)
+#define	__alloc_size(x)	__attribute__((__alloc_size__(x)))
+#define	__alloc_size2(n, x)	__attribute__((__alloc_size__(n, x)))
+#else
+#define	__alloc_size(x)
+#define	__alloc_size2(n, x)
+#endif
+#if __GNUC_PREREQ__(4, 9) || __has_attribute(__alloc_align__)
+#define	__alloc_align(x)	__attribute__((__alloc_align__(x)))
+#else
+#define	__alloc_align(x)
+#endif
+
+#if !__GNUC_PREREQ__(2, 95)
+#define	__alignof(x)	__offsetof(struct { char __a; x __b; }, __b)
+#endif
+
+/*
+ * Keywords added in C11.
+ */
+
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L
+
+#if !__has_extension(c_alignas)
+#if (defined(__cplusplus) && __cplusplus >= 201103L) || \
+    __has_extension(cxx_alignas)
+#define	_Alignas(x)		alignas(x)
+#else
+/* XXX: Only emulates _Alignas(constant-expression); not _Alignas(type-name). */
+#define	_Alignas(x)		__aligned(x)
+#endif
+#endif
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define	_Alignof(x)		alignof(x)
+#else
+#define	_Alignof(x)		__alignof(x)
+#endif
+
+#if !defined(__cplusplus) && !__has_extension(c_atomic) && \
+	!__has_extension(cxx_atomic) && !__GNUC_PREREQ__(4, 7)
+/*
+ * No native support for _Atomic(). Place object in structure to prevent
+ * most forms of direct non-atomic access.
+ */
+#define	_Atomic(T)		struct { T volatile __val; }
+#endif
+
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define	_Noreturn		[[noreturn]]
+#else
+#define	_Noreturn		__dead2
+#endif
+
+#if !__has_extension(c_static_assert)
+#if (defined(__cplusplus) && __cplusplus >= 201103L) || \
+    __has_extension(cxx_static_assert)
+#define	_Static_assert(x, y)	static_assert(x, y)
+#elif __GNUC_PREREQ__(4,6) && !defined(__cplusplus)
+/* Nothing, gcc 4.6 and higher has _Static_assert built-in */
+#elif defined(__COUNTER__)
+#define	_Static_assert(x, y)	__Static_assert(x, __COUNTER__)
+#define	__Static_assert(x, y)	___Static_assert(x, y)
+#define	___Static_assert(x, y)	typedef char __assert_ ## y[(x) ? 1 : -1] \
+				__unused
+#else
+#define	_Static_assert(x, y)	struct __hack
+#endif
+#endif
+
+#if !__has_extension(c_thread_local)
+/*
+ * XXX: Some compilers (Clang 3.3, GCC 4.7) falsely announce C++11 mode
+ * without actually supporting the thread_local keyword. Don't check for
+ * the presence of C++11 when defining _Thread_local.
+ */
+#if /* (defined(__cplusplus) && __cplusplus >= 201103L) || */ \
+    __has_extension(cxx_thread_local)
+#define	_Thread_local		thread_local
+#else
+#define	_Thread_local		__thread
+#endif
+#endif
+
+#endif /* __STDC_VERSION__ || __STDC_VERSION__ < 201112L */
+
+/*
+ * Emulation of C11 _Generic().  Unlike the previously defined C11
+ * keywords, it is not possible to implement this using exactly the same
+ * syntax.  Therefore implement something similar under the name
+ * __generic().  Unlike _Generic(), this macro can only distinguish
+ * between a single type, so it requires nested invocations to
+ * distinguish multiple cases.
+ */
+
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || \
+    __has_extension(c_generic_selections)
+#define	__generic(expr, t, yes, no)					\
+	_Generic(expr, t: yes, default: no)
+#elif __GNUC_PREREQ__(3, 1) && !defined(__cplusplus)
+#define	__generic(expr, t, yes, no)					\
+	__builtin_choose_expr(						\
+	    __builtin_types_compatible_p(__typeof(expr), t), yes, no)
+#endif
+
+/*
+ * C99 Static array indices in function parameter declarations.  Syntax such as:
+ * void bar(int myArray[static 10]);
+ * is allowed in C99 but not in C++.  Define __min_size appropriately so
+ * headers using it can be compiled in either language.  Use like this:
+ * void bar(int myArray[__min_size(10)]);
+ */
+#if !defined(__cplusplus) && \
+    (defined(__clang__) || __GNUC_PREREQ__(4, 6)) && \
+    (!defined(__STDC_VERSION__) || (__STDC_VERSION__ >= 199901))
+#define __min_size(x)	static (x)
+#else
+#define __min_size(x)	(x)
+#endif
+
+#if __GNUC_PREREQ__(2, 96)
+#define	__malloc_like	__attribute__((__malloc__))
+#define	__pure		__attribute__((__pure__))
+#else
+#define	__malloc_like
+#define	__pure
+#endif
+
+#if __GNUC_PREREQ__(3, 1)
+#define	__always_inline	__attribute__((__always_inline__))
+#else
+#define	__always_inline
+#endif
+
+#if __GNUC_PREREQ__(3, 1)
+#define	__noinline	__attribute__ ((__noinline__))
+#else
+#define	__noinline
+#endif
+
+#if __GNUC_PREREQ__(3, 4)
+#define	__fastcall	__attribute__((__fastcall__))
+#define	__result_use_check	__attribute__((__warn_unused_result__))
+#else
+#define	__fastcall
+#define	__result_use_check
+#endif
+
+#if __GNUC_PREREQ__(4, 1)
+#define	__returns_twice	__attribute__((__returns_twice__))
+#else
+#define	__returns_twice
+#endif
+
+#if __GNUC_PREREQ__(4, 6) || __has_builtin(__builtin_unreachable)
+#define	__unreachable()	__builtin_unreachable()
+#else
+#define	__unreachable()	((void)0)
+#endif
+
+/* XXX: should use `#if __STDC_VERSION__ < 199901'. */
+#if !__GNUC_PREREQ__(2, 7)
+#define	__func__	NULL
+#endif
+
+#if (defined(__GNUC__) && __GNUC__ >= 2) && !defined(__STRICT_ANSI__) || __STDC_VERSION__ >= 199901
+#define	__LONG_LONG_SUPPORTED
+#endif
+
+/* C++11 exposes a load of C99 stuff */
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#define	__LONG_LONG_SUPPORTED
+#ifndef	__STDC_LIMIT_MACROS
+#define	__STDC_LIMIT_MACROS
+#endif
+#ifndef	__STDC_CONSTANT_MACROS
+#define	__STDC_CONSTANT_MACROS
+#endif
+#endif
+
+/*
+ * GCC 2.95 provides `__restrict' as an extension to C90 to support the
+ * C99-specific `restrict' type qualifier.  We happen to use `__restrict' as
+ * a way to define the `restrict' type qualifier without disturbing older
+ * software that is unaware of C99 keywords.
+ */
+#if !(__GNUC__ == 2 && __GNUC_MINOR__ == 95)
+#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901
+#define	__restrict
+#else
+#define	__restrict	restrict
+#endif
+#endif
+
+/*
+ * GNU C version 2.96 adds explicit branch prediction so that
+ * the CPU back-end can hint the processor and also so that
+ * code blocks can be reordered such that the predicted path
+ * sees a more linear flow, thus improving cache behavior, etc.
+ *
+ * The following two macros provide us with a way to utilize this
+ * compiler feature.  Use __predict_true() if you expect the expression
+ * to evaluate to true, and __predict_false() if you expect the
+ * expression to evaluate to false.
+ *
+ * A few notes about usage:
+ *
+ *	* Generally, __predict_false() error condition checks (unless
+ *	  you have some _strong_ reason to do otherwise, in which case
+ *	  document it), and/or __predict_true() `no-error' condition
+ *	  checks, assuming you want to optimize for the no-error case.
+ *
+ *	* Other than that, if you don't know the likelihood of a test
+ *	  succeeding from empirical or other `hard' evidence, don't
+ *	  make predictions.
+ *
+ *	* These are meant to be used in places that are run `a lot'.
+ *	  It is wasteful to make predictions in code that is run
+ *	  seldomly (e.g. at subsystem initialization time) as the
+ *	  basic block reordering that this affects can often generate
+ *	  larger code.
+ */
+#if __GNUC_PREREQ__(2, 96)
+#define	__predict_true(exp)     __builtin_expect((exp), 1)
+#define	__predict_false(exp)    __builtin_expect((exp), 0)
+#else
+#define	__predict_true(exp)     (exp)
+#define	__predict_false(exp)    (exp)
+#endif
+
+#if __GNUC_PREREQ__(4, 0)
+#define	__null_sentinel	__attribute__((__sentinel__))
+#define	__exported	__attribute__((__visibility__("default")))
+#define	__hidden	__attribute__((__visibility__("hidden")))
+#else
+#define	__null_sentinel
+#define	__exported
+#define	__hidden
+#endif
+
+/*
+ * We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
+ * require it.
+ */
+#if __GNUC_PREREQ__(4, 1)
+#define	__offsetof(type, field)	 __builtin_offsetof(type, field)
+#else
+#ifndef __cplusplus
+#define	__offsetof(type, field) \
+	((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field))
+#else
+#define	__offsetof(type, field)					\
+  (__offsetof__ (reinterpret_cast <__size_t>			\
+                 (&reinterpret_cast <const volatile char &>	\
+                  (static_cast<type *> (0)->field))))
+#endif
+#endif
+#define	__rangeof(type, start, end) \
+	(__offsetof(type, end) - __offsetof(type, start))
+
+/*
+ * Given the pointer x to the member m of the struct s, return
+ * a pointer to the containing structure.  When using GCC, we first
+ * assign pointer x to a local variable, to check that its type is
+ * compatible with member m.
+ */
+#if __GNUC_PREREQ__(3, 1)
+#define	__containerof(x, s, m) ({					\
+	const volatile __typeof(((s *)0)->m) *__x = (x);		\
+	__DEQUALIFY(s *, (const volatile char *)__x - __offsetof(s, m));\
+})
+#else
+#define	__containerof(x, s, m)						\
+	__DEQUALIFY(s *, (const volatile char *)(x) - __offsetof(s, m))
+#endif
+
+/*
+ * Compiler-dependent macros to declare that functions take printf-like
+ * or scanf-like arguments.  They are null except for versions of gcc
+ * that are known to support the features properly (old versions of gcc-2
+ * didn't permit keeping the keywords out of the application namespace).
+ */
+#if !__GNUC_PREREQ__(2, 7)
+#define	__printflike(fmtarg, firstvararg)
+#define	__scanflike(fmtarg, firstvararg)
+#define	__format_arg(fmtarg)
+#define	__strfmonlike(fmtarg, firstvararg)
+#define	__strftimelike(fmtarg, firstvararg)
+#else
+#define	__printflike(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__printf__, fmtarg, firstvararg)))
+#define	__scanflike(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__scanf__, fmtarg, firstvararg)))
+#define	__format_arg(fmtarg)	__attribute__((__format_arg__ (fmtarg)))
+#define	__strfmonlike(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__strfmon__, fmtarg, firstvararg)))
+#define	__strftimelike(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__strftime__, fmtarg, firstvararg)))
+#endif
+
+/* Compiler-dependent macros that rely on FreeBSD-specific extensions. */
+#if defined(__FreeBSD_cc_version) && __FreeBSD_cc_version >= 300001 && \
+    defined(__GNUC__)
+#define	__printf0like(fmtarg, firstvararg) \
+	    __attribute__((__format__ (__printf0__, fmtarg, firstvararg)))
+#else
+#define	__printf0like(fmtarg, firstvararg)
+#endif
+
+#if defined(__GNUC__)
+#define	__strong_reference(sym,aliassym)	\
+	extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym)))
+#ifdef __STDC__
+#define	__weak_reference(sym,alias)	\
+	__asm__(".weak " #alias);	\
+	__asm__(".equ "  #alias ", " #sym)
+#define	__warn_references(sym,msg)	\
+	__asm__(".section .gnu.warning." #sym);	\
+	__asm__(".asciz \"" msg "\"");	\
+	__asm__(".previous")
+#define	__sym_compat(sym,impl,verid)	\
+	__asm__(".symver " #impl ", " #sym "@" #verid)
+#define	__sym_default(sym,impl,verid)	\
+	__asm__(".symver " #impl ", " #sym "@@@" #verid)
+#else
+#define	__weak_reference(sym,alias)	\
+	__asm__(".weak alias");		\
+	__asm__(".equ alias, sym")
+#define	__warn_references(sym,msg)	\
+	__asm__(".section .gnu.warning.sym"); \
+	__asm__(".asciz \"msg\"");	\
+	__asm__(".previous")
+#define	__sym_compat(sym,impl,verid)	\
+	__asm__(".symver impl, sym@verid")
+#define	__sym_default(impl,sym,verid)	\
+	__asm__(".symver impl, sym@@@verid")
+#endif	/* __STDC__ */
+#endif	/* __GNUC__ */
+
+#define	__GLOBL(sym)	__asm__(".globl " __XSTRING(sym))
+#define	__WEAK(sym)	__asm__(".weak " __XSTRING(sym))
+
+#if defined(__GNUC__)
+#define	__IDSTRING(name,string)	__asm__(".ident\t\"" string "\"")
+#else
+/*
+ * The following definition might not work well if used in header files,
+ * but it should be better than nothing.  If you want a "do nothing"
+ * version, then it should generate some harmless declaration, such as:
+ *    #define	__IDSTRING(name,string)	struct __hack
+ */
+#define	__IDSTRING(name,string)	static const char name[] __unused = string
+#endif
+
+/*
+ * Embed the rcs id of a source file in the resulting library.  Note that in
+ * more recent ELF binutils, we use .ident allowing the ID to be stripped.
+ * Usage:
+ *	__FBSDID("$FreeBSD$");
+ */
+#ifndef	__FBSDID
+#if !defined(STRIP_FBSDID)
+#define	__FBSDID(s)	__IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+#else
+#define	__FBSDID(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__RCSID
+#ifndef	NO__RCSID
+#define	__RCSID(s)	__IDSTRING(__CONCAT(__rcsid_,__LINE__),s)
+#else
+#define	__RCSID(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__RCSID_SOURCE
+#ifndef	NO__RCSID_SOURCE
+#define	__RCSID_SOURCE(s)	__IDSTRING(__CONCAT(__rcsid_source_,__LINE__),s)
+#else
+#define	__RCSID_SOURCE(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__SCCSID
+#ifndef	NO__SCCSID
+#define	__SCCSID(s)	__IDSTRING(__CONCAT(__sccsid_,__LINE__),s)
+#else
+#define	__SCCSID(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__COPYRIGHT
+#ifndef	NO__COPYRIGHT
+#define	__COPYRIGHT(s)	__IDSTRING(__CONCAT(__copyright_,__LINE__),s)
+#else
+#define	__COPYRIGHT(s)	struct __hack
+#endif
+#endif
+
+#ifndef	__DECONST
+#define	__DECONST(type, var)	((type)(__uintptr_t)(const void *)(var))
+#endif
+
+#ifndef	__DEVOLATILE
+#define	__DEVOLATILE(type, var)	((type)(__uintptr_t)(volatile void *)(var))
+#endif
+
+#ifndef	__DEQUALIFY
+#define	__DEQUALIFY(type, var)	((type)(__uintptr_t)(const volatile void *)(var))
+#endif
+
+/*-
+ * The following definitions are an extension of the behavior originally
+ * implemented in <sys/_posix.h>, but with a different level of granularity.
+ * POSIX.1 requires that the macros we test be defined before any standard
+ * header file is included.
+ *
+ * Here's a quick run-down of the versions (and some informal names)
+ *  defined(_POSIX_SOURCE)		1003.1-1988
+ *					encoded as 198808 below
+ *  _POSIX_C_SOURCE == 1		1003.1-1990
+ *					encoded as 199009 below
+ *  _POSIX_C_SOURCE == 2		1003.2-1992 C Language Binding Option
+ *					encoded as 199209 below
+ *  _POSIX_C_SOURCE == 199309		1003.1b-1993
+ *					(1003.1 Issue 4, Single Unix Spec v1, Unix 93)
+ *  _POSIX_C_SOURCE == 199506		1003.1c-1995, 1003.1i-1995,
+ *					and the omnibus ISO/IEC 9945-1: 1996
+ *					(1003.1 Issue 5, Single	Unix Spec v2, Unix 95)
+ *  _POSIX_C_SOURCE == 200112		1003.1-2001 (1003.1 Issue 6, Unix 03)
+ *  _POSIX_C_SOURCE == 200809		1003.1-2008 (1003.1 Issue 7)
+ *					IEEE Std 1003.1-2017 (Rev of 1003.1-2008) is
+ *					1003.1-2008 with two TCs applied with
+ *					_POSIX_C_SOURCE=200809 and _XOPEN_SOURCE=700
+ *
+ * In addition, the X/Open Portability Guide, which is now the Single UNIX
+ * Specification, defines a feature-test macro which indicates the version of
+ * that specification, and which subsumes _POSIX_C_SOURCE.
+ *
+ * Our macros begin with two underscores to avoid namespace screwage.
+ */
+
+/* Deal with IEEE Std. 1003.1-1990, in which _POSIX_C_SOURCE == 1. */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 1
+#undef _POSIX_C_SOURCE		/* Probably illegal, but beyond caring now. */
+#define	_POSIX_C_SOURCE		199009
+#endif
+
+/* Deal with IEEE Std. 1003.2-1992, in which _POSIX_C_SOURCE == 2. */
+#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE == 2
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		199209
+#endif
+
+/* Deal with various X/Open Portability Guides and Single UNIX Spec. */
+#ifdef _XOPEN_SOURCE
+#if _XOPEN_SOURCE - 0 >= 700
+#define	__XSI_VISIBLE		700
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		200809
+#elif _XOPEN_SOURCE - 0 >= 600
+#define	__XSI_VISIBLE		600
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		200112
+#elif _XOPEN_SOURCE - 0 >= 500
+#define	__XSI_VISIBLE		500
+#undef _POSIX_C_SOURCE
+#define	_POSIX_C_SOURCE		199506
+#endif
+#endif
+
+/*
+ * Deal with all versions of POSIX.  The ordering relative to the tests above is
+ * important.
+ */
+#if defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE)
+#define	_POSIX_C_SOURCE		198808
+#endif
+#ifdef _POSIX_C_SOURCE
+#if _POSIX_C_SOURCE >= 200809
+#define	__POSIX_VISIBLE		200809
+#define	__ISO_C_VISIBLE		1999
+#elif _POSIX_C_SOURCE >= 200112
+#define	__POSIX_VISIBLE		200112
+#define	__ISO_C_VISIBLE		1999
+#elif _POSIX_C_SOURCE >= 199506
+#define	__POSIX_VISIBLE		199506
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199309
+#define	__POSIX_VISIBLE		199309
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199209
+#define	__POSIX_VISIBLE		199209
+#define	__ISO_C_VISIBLE		1990
+#elif _POSIX_C_SOURCE >= 199009
+#define	__POSIX_VISIBLE		199009
+#define	__ISO_C_VISIBLE		1990
+#else
+#define	__POSIX_VISIBLE		198808
+#define	__ISO_C_VISIBLE		0
+#endif /* _POSIX_C_SOURCE */
+/*
+ * Both glibc and OpenBSD enable c11 features when _ISOC11_SOURCE is defined, or
+ * when compiling with -stdc=c11. A strict reading of the standard would suggest
+ * doing it only for the former. However, a strict reading also requires C99
+ * mode only, so building with C11 is already undefined. Follow glibc's and
+ * OpenBSD's lead for this non-standard configuration for maximum compatibility.
+ */
+#if _ISOC11_SOURCE || (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L)
+#undef __ISO_C_VISIBLE
+#define __ISO_C_VISIBLE		2011
+#endif
+#else
+/*-
+ * Deal with _ANSI_SOURCE:
+ * If it is defined, and no other compilation environment is explicitly
+ * requested, then define our internal feature-test macros to zero.  This
+ * makes no difference to the preprocessor (undefined symbols in preprocessing
+ * expressions are defined to have value zero), but makes it more convenient for
+ * a test program to print out the values.
+ *
+ * If a program mistakenly defines _ANSI_SOURCE and some other macro such as
+ * _POSIX_C_SOURCE, we will assume that it wants the broader compilation
+ * environment (and in fact we will never get here).
+ */
+#if defined(_ANSI_SOURCE)	/* Hide almost everything. */
+#define	__POSIX_VISIBLE		0
+#define	__XSI_VISIBLE		0
+#define	__BSD_VISIBLE		0
+#define	__ISO_C_VISIBLE		1990
+#define	__EXT1_VISIBLE		0
+#elif defined(_C99_SOURCE)	/* Localism to specify strict C99 env. */
+#define	__POSIX_VISIBLE		0
+#define	__XSI_VISIBLE		0
+#define	__BSD_VISIBLE		0
+#define	__ISO_C_VISIBLE		1999
+#define	__EXT1_VISIBLE		0
+#elif defined(_C11_SOURCE)	/* Localism to specify strict C11 env. */
+#define	__POSIX_VISIBLE		0
+#define	__XSI_VISIBLE		0
+#define	__BSD_VISIBLE		0
+#define	__ISO_C_VISIBLE		2011
+#define	__EXT1_VISIBLE		0
+#else				/* Default environment: show everything. */
+#define	__POSIX_VISIBLE		200809
+#define	__XSI_VISIBLE		700
+#define	__BSD_VISIBLE		1
+#define	__ISO_C_VISIBLE		2011
+#define	__EXT1_VISIBLE		1
+#endif
+#endif
+
+/* User override __EXT1_VISIBLE */
+#if defined(__STDC_WANT_LIB_EXT1__)
+#undef	__EXT1_VISIBLE
+#if __STDC_WANT_LIB_EXT1__
+#define	__EXT1_VISIBLE		1
+#else
+#define	__EXT1_VISIBLE		0
+#endif
+#endif /* __STDC_WANT_LIB_EXT1__ */
+
+/*
+ * Old versions of GCC use non-standard ARM arch symbols; acle-compat.h
+ * translates them to __ARM_ARCH and the modern feature symbols defined by ARM.
+ */
+#if defined(__arm__) && !defined(__ARM_ARCH)
+#include <machine/acle-compat.h>
+#endif
+
+/*
+ * Nullability qualifiers: currently only supported by Clang.
+ */
+#if !(defined(__clang__) && __has_feature(nullability))
+#define	_Nonnull
+#define	_Nullable
+#define	_Null_unspecified
+#define	__NULLABILITY_PRAGMA_PUSH
+#define	__NULLABILITY_PRAGMA_POP
+#else
+#define	__NULLABILITY_PRAGMA_PUSH _Pragma("clang diagnostic push")	\
+	_Pragma("clang diagnostic ignored \"-Wnullability-completeness\"")
+#define	__NULLABILITY_PRAGMA_POP _Pragma("clang diagnostic pop")
+#endif
+
+/*
+ * Type Safety Checking
+ *
+ * Clang provides additional attributes to enable checking type safety
+ * properties that cannot be enforced by the C type system. 
+ */
+
+#if __has_attribute(__argument_with_type_tag__) && \
+    __has_attribute(__type_tag_for_datatype__)
+#define	__arg_type_tag(arg_kind, arg_idx, type_tag_idx) \
+	    __attribute__((__argument_with_type_tag__(arg_kind, arg_idx, type_tag_idx)))
+#define	__datatype_type_tag(kind, type) \
+	    __attribute__((__type_tag_for_datatype__(kind, type)))
+#else
+#define	__arg_type_tag(arg_kind, arg_idx, type_tag_idx)
+#define	__datatype_type_tag(kind, type)
+#endif
+
+/*
+ * Lock annotations.
+ *
+ * Clang provides support for doing basic thread-safety tests at
+ * compile-time, by marking which locks will/should be held when
+ * entering/leaving a functions.
+ *
+ * Furthermore, it is also possible to annotate variables and structure
+ * members to enforce that they are only accessed when certain locks are
+ * held.
+ */
+
+#if __has_extension(c_thread_safety_attributes)
+#define	__lock_annotate(x)	__attribute__((x))
+#else
+#define	__lock_annotate(x)
+#endif
+
+/* Structure implements a lock. */
+#define	__lockable		__lock_annotate(lockable)
+
+/* Function acquires an exclusive or shared lock. */
+#define	__locks_exclusive(...) \
+	__lock_annotate(exclusive_lock_function(__VA_ARGS__))
+#define	__locks_shared(...) \
+	__lock_annotate(shared_lock_function(__VA_ARGS__))
+
+/* Function attempts to acquire an exclusive or shared lock. */
+#define	__trylocks_exclusive(...) \
+	__lock_annotate(exclusive_trylock_function(__VA_ARGS__))
+#define	__trylocks_shared(...) \
+	__lock_annotate(shared_trylock_function(__VA_ARGS__))
+
+/* Function releases a lock. */
+#define	__unlocks(...)		__lock_annotate(unlock_function(__VA_ARGS__))
+
+/* Function asserts that an exclusive or shared lock is held. */
+#define	__asserts_exclusive(...) \
+	__lock_annotate(assert_exclusive_lock(__VA_ARGS__))
+#define	__asserts_shared(...) \
+	__lock_annotate(assert_shared_lock(__VA_ARGS__))
+
+/* Function requires that an exclusive or shared lock is or is not held. */
+#define	__requires_exclusive(...) \
+	__lock_annotate(exclusive_locks_required(__VA_ARGS__))
+#define	__requires_shared(...) \
+	__lock_annotate(shared_locks_required(__VA_ARGS__))
+#define	__requires_unlocked(...) \
+	__lock_annotate(locks_excluded(__VA_ARGS__))
+
+/* Function should not be analyzed. */
+#define	__no_lock_analysis	__lock_annotate(no_thread_safety_analysis)
+
+/*
+ * Function or variable should not be sanitized, e.g., by AddressSanitizer.
+ * GCC has the nosanitize attribute, but as a function attribute only, and
+ * warns on use as a variable attribute.
+ */
+#if __has_attribute(no_sanitize) && defined(__clang__)
+#ifdef _KERNEL
+#define __nosanitizeaddress	__attribute__((no_sanitize("kernel-address")))
+#define __nosanitizememory	__attribute__((no_sanitize("kernel-memory")))
+#else
+#define __nosanitizeaddress	__attribute__((no_sanitize("address")))
+#define __nosanitizememory	__attribute__((no_sanitize("memory")))
+#endif
+#define __nosanitizethread	__attribute__((no_sanitize("thread")))
+#else
+#define __nosanitizeaddress
+#define __nosanitizememory
+#define __nosanitizethread
+#endif
+
+/* Guard variables and structure members by lock. */
+#define	__guarded_by(x)		__lock_annotate(guarded_by(x))
+#define	__pt_guarded_by(x)	__lock_annotate(pt_guarded_by(x))
+
+/* Alignment builtins for better type checking and improved code generation. */
+/* Provide fallback versions for other compilers (GCC/Clang < 10): */
+#if !__has_builtin(__builtin_is_aligned)
+#define __builtin_is_aligned(x, align)	\
+	(((__uintptr_t)x & ((align) - 1)) == 0)
+#endif
+#if !__has_builtin(__builtin_align_up)
+#define __builtin_align_up(x, align)	\
+	((__typeof__(x))(((__uintptr_t)(x)+((align)-1))&(~((align)-1))))
+#endif
+#if !__has_builtin(__builtin_align_down)
+#define __builtin_align_down(x, align)	\
+	((__typeof__(x))((x)&(~((align)-1))))
+#endif
+
+#define __align_up(x, y) __builtin_align_up(x, y)
+#define __align_down(x, y) __builtin_align_down(x, y)
+#define __is_aligned(x, y) __builtin_is_aligned(x, y)
+
+#endif /* !_SYS_CDEFS_H_ */
diff --git a/components/common/libc/include/time.h b/components/common/libc/include/time.h
new file mode 100644
index 0000000..e1eb2a5
--- /dev/null
+++ b/components/common/libc/include/time.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2012-2017 Roberto E. Vargas Caballero
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+/*
+ * Portions copyright (c) 2018-2019, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#ifndef TIME_H
+#define TIME_H
+
+#include <stddef.h>
+
+typedef long int time_t;
+
+#endif /* TIME_H */
diff --git a/components/common/libc/src/abort.c b/components/common/libc/src/abort.c
new file mode 100644
index 0000000..c5a7920
--- /dev/null
+++ b/components/common/libc/src/abort.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <cdefs.h>
+#include "libc_platform.h"
+
+void __dead2 abort(void)
+{
+	platform_abort();
+}
diff --git a/components/common/libc/src/assert.c b/components/common/libc/src/assert.c
new file mode 100644
index 0000000..f6d33a5
--- /dev/null
+++ b/components/common/libc/src/assert.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2013-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+
+#ifndef NDEBUG
+#include "libc_platform.h"
+
+void __dead2 __assert(const char *file, int line, const char *func, const char *assertion)
+{
+	platform_assert(file, line, func, assertion);
+}
+#endif
diff --git a/components/common/libc/src/ctype.c b/components/common/libc/src/ctype.c
new file mode 100644
index 0000000..f7a1bd2
--- /dev/null
+++ b/components/common/libc/src/ctype.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <ctype.h>
+
+int isalnum(int c)
+{
+	return isalpha(c) || isdigit(c);
+}
+
+int isalpha(int c)
+{
+	return isupper(c) || islower(c);
+}
+
+int iscntrl(int c)
+{
+	return c < 0x20 || c == 0x7f;
+}
+
+int isdigit(int c)
+{
+	return c >= '0' && c <= '9';
+}
+
+int isgraph(int c)
+{
+	return c >= 0x21 && c < 0x7f;
+}
+
+int islower(int c)
+{
+	return c >= 'a' && c <= 'z';
+}
+
+int isprint(int c)
+{
+	return c >= 0x20 && c < 0x7f;
+}
+
+int ispunct(int c)
+{
+	return isgraph(c) && !isalnum(c);
+}
+
+int isspace(int c)
+{
+	return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
+}
+
+int isupper(int c)
+{
+	return c >= 'A' && c <= 'Z';
+}
+
+int isxdigit(int c)
+{
+	if (isdigit(c))
+		return 1;
+
+	if (c >= 'A' && c <= 'F')
+		return 1;
+
+	if (c >= 'a' && c <= 'f')
+		return 1;
+
+	return 0;
+}
+
+int tolower(int c)
+{
+	if (c >= 'A' && c <= 'Z')
+		return c - 'A' + 'a';
+
+	return c;
+}
+
+int toupper(int c)
+{
+	if (c >= 'a' && c <= 'z')
+		return c - 'a' + 'A';
+
+	return c;
+}
diff --git a/components/common/libc/src/exit.c b/components/common/libc/src/exit.c
new file mode 100644
index 0000000..6de2e93
--- /dev/null
+++ b/components/common/libc/src/exit.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2015-2018, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdlib.h>
+
+static void (*exitfun)(void);
+
+void exit(int status)
+{
+	if (exitfun != NULL)
+		(*exitfun)();
+	for (;;)
+		;
+}
+
+int atexit(void (*fun)(void))
+{
+	if (exitfun != NULL)
+		return -1;
+	exitfun = fun;
+
+	return 0;
+}
diff --git a/components/common/libc/src/memchr.c b/components/common/libc/src/memchr.c
new file mode 100644
index 0000000..66d7ba1
--- /dev/null
+++ b/components/common/libc/src/memchr.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+void *memchr(const void *src, int c, size_t len)
+{
+	const unsigned char *s = src;
+
+	while (len--) {
+		if (*s == (unsigned char)c)
+			return (void *) s;
+		s++;
+	}
+
+	return NULL;
+}
diff --git a/components/common/libc/src/memcmp.c b/components/common/libc/src/memcmp.c
new file mode 100644
index 0000000..db2701b
--- /dev/null
+++ b/components/common/libc/src/memcmp.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+int memcmp(const void *s1, const void *s2, size_t len)
+{
+	const unsigned char *s = s1;
+	const unsigned char *d = s2;
+	unsigned char sc;
+	unsigned char dc;
+
+	while (len--) {
+		sc = *s++;
+		dc = *d++;
+		if (sc - dc)
+			return (sc - dc);
+	}
+
+	return 0;
+}
diff --git a/components/common/libc/src/memcpy.c b/components/common/libc/src/memcpy.c
new file mode 100644
index 0000000..af9ed45
--- /dev/null
+++ b/components/common/libc/src/memcpy.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+void *memcpy(void *dst, const void *src, size_t len)
+{
+	const char *s = src;
+	char *d = dst;
+
+	while (len--)
+		*d++ = *s++;
+
+	return dst;
+}
diff --git a/components/common/libc/src/memcpy_s.c b/components/common/libc/src/memcpy_s.c
new file mode 100644
index 0000000..26953bf
--- /dev/null
+++ b/components/common/libc/src/memcpy_s.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+int memcpy_s(void *dst, size_t dsize, void *src, size_t ssize)
+{
+	unsigned int *s = (unsigned int *)src;
+	unsigned int *d = (unsigned int *)dst;
+
+	/*
+	 * Check source and destination size is NULL
+	 */
+	if ((dst == NULL) || (src == NULL)) {
+		return -ENOMEM;
+	}
+
+	/*
+	 * Check source and destination size validity
+	 */
+	if ((dsize == 0) || (ssize == 0)) {
+		return -ERANGE;
+	}
+
+	/*
+	 * Check both source and destination size range
+	 */
+	if ((ssize > dsize) || (dsize > ssize)) {
+		return -EINVAL;
+	}
+
+	/*
+	 * Check both source and destination address overlapping
+	 * When (s > d < s + ssize)
+	 * Or (d > s < d + dsize)
+	 */
+
+	if (d > s) {
+		if ((d) < (s + ssize)) {
+			return -EOPNOTSUPP;
+		}
+	}
+
+	if (s > d) {
+		if ((s) < (d + dsize)) {
+			return -EOPNOTSUPP;
+		}
+	}
+
+	/*
+	 * Start copy process when there is no error
+	 */
+	while (ssize--) {
+		d[ssize] = s[ssize];
+	}
+
+	return 0;
+}
diff --git a/components/common/libc/src/memmove.c b/components/common/libc/src/memmove.c
new file mode 100644
index 0000000..5c2b661
--- /dev/null
+++ b/components/common/libc/src/memmove.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+void *memmove(void *dst, const void *src, size_t len)
+{
+	/*
+	 * The following test makes use of unsigned arithmetic overflow to
+	 * more efficiently test the condition !(src <= dst && dst < str+len).
+	 * It also avoids the situation where the more explicit test would give
+	 * incorrect results were the calculation str+len to overflow (though
+	 * that issue is probably moot as such usage is probably undefined
+	 * behaviour and a bug anyway.
+	 */
+	if ((size_t)dst - (size_t)src >= len) {
+		/* destination not in source data, so can safely use memcpy */
+		return memcpy(dst, src, len);
+	} else {
+		/* copy backwards... */
+		const char *end = dst;
+		const char *s = (const char *)src + len;
+		char *d = (char *)dst + len;
+		while (d != end)
+			*--d = *--s;
+	}
+	return dst;
+}
diff --git a/components/common/libc/src/memrchr.c b/components/common/libc/src/memrchr.c
new file mode 100644
index 0000000..01caef3
--- /dev/null
+++ b/components/common/libc/src/memrchr.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+#undef memrchr
+
+void *memrchr(const void *src, int c, size_t len)
+{
+	const unsigned char *s = src + (len - 1);
+
+	while (len--) {
+		if (*s == (unsigned char)c) {
+			return (void*) s;
+		}
+
+		s--;
+	}
+
+	return NULL;
+}
diff --git a/components/common/libc/src/memset.c b/components/common/libc/src/memset.c
new file mode 100644
index 0000000..c5bac8d
--- /dev/null
+++ b/components/common/libc/src/memset.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdint.h>
+
+void *memset(void *dst, int val, size_t count)
+{
+	uint8_t *ptr = dst;
+	uint64_t *ptr64;
+	uint64_t fill = (unsigned char)val;
+
+	/* Simplify code below by making sure we write at least one byte. */
+	if (count == 0U) {
+		return dst;
+	}
+
+	/* Handle the first part, until the pointer becomes 64-bit aligned. */
+	while (((uintptr_t)ptr & 7U) != 0U) {
+		*ptr = (uint8_t)val;
+		ptr++;
+		if (--count == 0U) {
+			return dst;
+		}
+	}
+
+	/* Duplicate the fill byte to the rest of the 64-bit word. */
+	fill |= fill << 8;
+	fill |= fill << 16;
+	fill |= fill << 32;
+
+	/* Use 64-bit writes for as long as possible. */
+	ptr64 = (uint64_t *)ptr;
+	for (; count >= 8U; count -= 8) {
+		*ptr64 = fill;
+		ptr64++;
+	}
+
+	/* Handle the remaining part byte-per-byte. */
+	ptr = (uint8_t *)ptr64;
+	while (count-- > 0U)  {
+		*ptr = (uint8_t)val;
+		ptr++;
+	}
+
+	return dst;
+}
diff --git a/components/common/libc/src/printf.c b/components/common/libc/src/printf.c
new file mode 100644
index 0000000..a856345
--- /dev/null
+++ b/components/common/libc/src/printf.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2014-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#define get_num_va_args(_args, _lcount)				\
+	(((_lcount) > 1)  ? va_arg(_args, long long int) :	\
+	(((_lcount) == 1) ? va_arg(_args, long int) :		\
+			    va_arg(_args, int)))
+
+#define get_unum_va_args(_args, _lcount)				\
+	(((_lcount) > 1)  ? va_arg(_args, unsigned long long int) :	\
+	(((_lcount) == 1) ? va_arg(_args, unsigned long int) :		\
+			    va_arg(_args, unsigned int)))
+
+static int string_print(const char *str)
+{
+	int count = 0;
+
+	assert(str != NULL);
+
+	for ( ; *str != '\0'; str++) {
+		(void)putchar(*str);
+		count++;
+	}
+
+	return count;
+}
+
+static int unsigned_num_print(unsigned long long int unum, unsigned int radix,
+			      char padc, int padn, bool uppercase)
+{
+	/* Just need enough space to store 64 bit decimal integer */
+	char num_buf[20];
+	int i = 0, count = 0;
+	unsigned int rem;
+
+	/* num_buf is only large enough for radix >= 10 */
+	if (radix < 10) {
+		assert(0);
+		return 0;
+	}
+
+	do {
+		rem = unum % radix;
+		if (rem < 0xa) {
+			num_buf[i] = '0' + rem;
+		} else if (uppercase) {
+			num_buf[i] = 'A' + (rem - 0xa);
+		} else {
+			num_buf[i] = 'a' + (rem - 0xa);
+		}
+		i++;
+		unum /= radix;
+	} while (unum > 0U);
+
+	if (padn > 0) {
+		while (i < padn) {
+			(void)putchar(padc);
+			count++;
+			padn--;
+		}
+	}
+
+	while (--i >= 0) {
+		(void)putchar(num_buf[i]);
+		count++;
+	}
+
+	return count;
+}
+
+/*******************************************************************
+ * Reduced format print for Trusted firmware.
+ * The following type specifiers are supported by this print
+ * %x - hexadecimal format
+ * %s - string format
+ * %d or %i - signed decimal format
+ * %c - character format
+ * %u - unsigned decimal format
+ * %p - pointer format
+ *
+ * The following length specifiers are supported by this print
+ * %l - long int (64-bit on AArch64)
+ * %ll - long long int (64-bit on AArch64)
+ * %z - size_t sized integer formats (64 bit on AArch64)
+ *
+ * The following padding specifiers are supported by this print
+ * %0NN - Left-pad the number with 0s (NN is a decimal number)
+ * %NN - Left-pad the number with spaces (NN is a decimal number)
+ *
+ * The print exits on all other formats specifiers other than valid
+ * combinations of the above specifiers.
+ *******************************************************************/
+int vprintf(const char *fmt, va_list args)
+{
+	int l_count;
+	long long int num;
+	unsigned long long int unum;
+	char *str;
+	char padc = '\0'; /* Padding character */
+	int padn; /* Number of characters to pad */
+	int count = 0; /* Number of printed characters */
+	bool uppercase; /* Print characters in uppercase */
+
+	while (*fmt != '\0') {
+		uppercase = false;
+		l_count = 0;
+		padn = 0;
+
+		if (*fmt == '%') {
+			fmt++;
+			/* Check the format specifier */
+loop:
+			switch (*fmt) {
+			case '%':
+				(void)putchar('%');
+				break;
+			case 'i': /* Fall through to next one */
+			case 'd':
+				num = get_num_va_args(args, l_count);
+				if (num < 0) {
+					(void)putchar('-');
+					unum = (unsigned long long int)-num;
+					padn--;
+				} else
+					unum = (unsigned long long int)num;
+
+				count += unsigned_num_print(unum, 10,
+							    padc, padn, uppercase);
+				break;
+			case 'c':
+				(void)putchar(va_arg(args, int));
+				count++;
+				break;
+			case 's':
+				str = va_arg(args, char *);
+				count += string_print(str);
+				break;
+			case 'p':
+				unum = (uintptr_t)va_arg(args, void *);
+				if (unum > 0U) {
+					count += string_print("0x");
+					padn -= 2;
+				}
+
+				count += unsigned_num_print(unum, 16,
+							    padc, padn, uppercase);
+				break;
+			case 'X':
+				uppercase = true;
+				// fall through
+			case 'x':
+				unum = get_unum_va_args(args, l_count);
+				count += unsigned_num_print(unum, 16,
+							    padc, padn, uppercase);
+				break;
+			case 'z':
+				if (sizeof(size_t) == 8U)
+					l_count = 2;
+
+				fmt++;
+				goto loop;
+			case 'l':
+				l_count++;
+				fmt++;
+				goto loop;
+			case 'u':
+				unum = get_unum_va_args(args, l_count);
+				count += unsigned_num_print(unum, 10,
+							    padc, padn, uppercase);
+				break;
+			case '0':
+				padc = '0';
+				padn = 0;
+				fmt++;
+
+				for (;;) {
+					char ch = *fmt;
+					if ((ch < '0') || (ch > '9')) {
+						goto loop;
+					}
+					padn = (padn * 10) + (ch - '0');
+					fmt++;
+				}
+				assert(0); /* Unreachable */
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				padc = ' ';
+				padn = 0;
+
+				for (;;) {
+					char ch = *fmt;
+					if ((ch < '0') || (ch > '9')) {
+						goto loop;
+					}
+					padn = (padn * 10) + (ch - '0');
+					fmt++;
+				}
+				assert(0); /* Unreachable */
+			default:
+				/* Exit on any other format specifier */
+				return -1;
+			}
+			fmt++;
+			continue;
+		}
+		(void)putchar(*fmt);
+		fmt++;
+		count++;
+	}
+
+	return count;
+}
+
+int printf(const char *fmt, ...)
+{
+	int count;
+	va_list va;
+
+	va_start(va, fmt);
+	count = vprintf(fmt, va);
+	va_end(va);
+
+	return count;
+}
diff --git a/components/common/libc/src/putchar.c b/components/common/libc/src/putchar.c
new file mode 100644
index 0000000..1f919d1
--- /dev/null
+++ b/components/common/libc/src/putchar.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2013-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+
+#pragma weak putchar
+int putchar(int c)
+{
+	return c;
+}
diff --git a/components/common/libc/src/puts.c b/components/common/libc/src/puts.c
new file mode 100644
index 0000000..f57fc98
--- /dev/null
+++ b/components/common/libc/src/puts.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2013-2018, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdio.h>
+
+int puts(const char *s)
+{
+	int count = 0;
+
+	while (*s != '\0') {
+		if (putchar(*s) == EOF)
+			return EOF;
+		s++;
+		count++;
+	}
+
+	if (putchar('\n') == EOF)
+		return EOF;
+
+	return count + 1;
+}
diff --git a/components/common/libc/src/snprintf.c b/components/common/libc/src/snprintf.c
new file mode 100644
index 0000000..21d3416
--- /dev/null
+++ b/components/common/libc/src/snprintf.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#define get_num_va_args(_args, _lcount)				\
+	(((_lcount) > 1)  ? va_arg(_args, long long int) :	\
+	(((_lcount) == 1) ? va_arg(_args, long int) :		\
+			    va_arg(_args, int)))
+
+#define get_unum_va_args(_args, _lcount)				\
+	(((_lcount) > 1)  ? va_arg(_args, unsigned long long int) :	\
+	(((_lcount) == 1) ? va_arg(_args, unsigned long int) :		\
+			    va_arg(_args, unsigned int)))
+
+#define CHECK_AND_PUT_CHAR(buf, size, chars_printed, ch)	\
+	do {						\
+		if ((chars_printed) < (size)) {		\
+			*(buf) = (ch);			\
+			(buf)++;			\
+		}					\
+		(chars_printed)++;			\
+	} while (false)
+
+static void string_print(char **s, size_t n, size_t *chars_printed,
+			 const char *str)
+{
+	while (*str != '\0') {
+		CHECK_AND_PUT_CHAR(*s, n, *chars_printed, *str);
+		str++;
+	}
+}
+
+static void unsigned_num_print(char **s, size_t n, size_t *chars_printed,
+			      unsigned long long int unum,
+			      unsigned int radix, char padc, int padn,
+			      bool capitalise)
+{
+	/* Just need enough space to store 64 bit decimal integer */
+	char num_buf[20];
+	int i = 0;
+	int width;
+	unsigned int rem;
+	char ascii_a = capitalise ? 'A' : 'a';
+
+	/* num_buf is only large enough for radix >= 10 */
+	if (radix < 10) {
+		assert(0);
+		return;
+	}
+
+	do {
+		rem = unum % radix;
+		if (rem < 10U) {
+			num_buf[i] = '0' + rem;
+		} else {
+			num_buf[i] = ascii_a + (rem - 10U);
+		}
+		i++;
+		unum /= radix;
+	} while (unum > 0U);
+
+	width = i;
+	for (i = padn - width; i > 0; i--) {
+		CHECK_AND_PUT_CHAR(*s, n, *chars_printed, padc);
+	}
+	for (i = width; i > 0; i--) {
+		CHECK_AND_PUT_CHAR(*s, n, *chars_printed, num_buf[i - 1]);
+	}
+	for (i = width + padn; i < 0; i++) {
+		CHECK_AND_PUT_CHAR(*s, n, *chars_printed, padc);
+	}
+}
+
+/*******************************************************************
+ * Reduced vsnprintf to be used for Trusted firmware.
+ * The following type specifiers are supported:
+ *
+ * %x (or %X) - hexadecimal format
+ * %d or %i - signed decimal format
+ * %c - character format
+ * %s - string format
+ * %u - unsigned decimal format
+ * %p - pointer format
+ *
+ * The following length specifiers are supported by this print
+ * %l - long int
+ * %ll - long long int
+ * %z - size_t sized integer formats
+ *
+ * The following padding specifiers are supported by this print
+ * %0NN - Left-pad the number with 0s (NN is a decimal number)
+ * %NN - Left-pad the number or string with spaces (NN is a decimal number)
+ * %-NN - Right-pad the number or string with spaces (NN is a decimal number)
+ *
+ * The function panics on all other formats specifiers.
+ *
+ * It returns the number of characters that would be written if the
+ * buffer was big enough. If it returns a value lower than n, the
+ * whole string has been written.
+ *******************************************************************/
+int vsnprintf(char *s, size_t n, const char *fmt, va_list args)
+{
+	int num;
+	unsigned long long int unum;
+	char *str;
+	char padc;		/* Padding character */
+	int padn;		/* Number of characters to pad */
+	bool left;
+	bool capitalise;
+	size_t chars_printed = 0U;
+	unsigned int l_count;
+
+	if (n == 0U) {
+		/* There isn't space for anything. */
+	} else if (n == 1U) {
+		/* Buffer is too small to actually write anything else. */
+		*s = '\0';
+		n = 0U;
+	} else {
+		/* Reserve space for the terminator character. */
+		n--;
+	}
+
+	while (*fmt != '\0') {
+		left = false;
+		padc ='\0';
+		padn = 0;
+		capitalise = false;
+		l_count = 0;
+
+		if (*fmt == '%') {
+			fmt++;
+			/* Check the format specifier. */
+loop:
+			switch (*fmt) {
+			case '%':
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, '%');
+				break;
+			case '0':
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+				padc = (*fmt == '0') ? '0' : ' ';
+				for (padn = 0; *fmt >= '0' && *fmt <= '9'; fmt++) {
+					padn = (padn * 10) + (*fmt - '0');
+				}
+				if (left) {
+					padn = -padn;
+				}
+				goto loop;
+			case '-':
+				left = true;
+				fmt++;
+				goto loop;
+
+			case 'i':
+			case 'd':
+				num = get_num_va_args(args, l_count);
+
+				if (num < 0) {
+					CHECK_AND_PUT_CHAR(s, n, chars_printed,
+						'-');
+					unum = (unsigned int)-num;
+				} else {
+					unum = (unsigned int)num;
+				}
+
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 10, padc, padn, false);
+				break;
+			case 'c':
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, va_arg(args, int));
+				break;
+			case 's':
+				str = va_arg(args, char *);
+				string_print(&s, n, &chars_printed, str);
+				break;
+			case 'u':
+				unum = get_unum_va_args(args, l_count);
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 10, padc, padn, false);
+				break;
+			case 'z':
+				l_count = 1;
+				fmt++;
+				goto loop;
+			case 'l':
+				l_count++;
+				fmt++;
+				goto loop;
+			case 'p':
+				unum = (uintptr_t)va_arg(args, void *);
+				if (unum > 0U) {
+					string_print(&s, n, &chars_printed, "0x");
+					padn -= 2;
+				}
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 16, padc, padn, false);
+				break;
+			case 'X':
+				capitalise = true;
+				/* fallthrough */
+			case 'x':
+				unum = get_unum_va_args(args, l_count);
+				unsigned_num_print(&s, n, &chars_printed,
+						   unum, 16, padc, padn,
+						   capitalise);
+				break;
+
+			default:
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, '%');
+				CHECK_AND_PUT_CHAR(s, n, chars_printed, *fmt);
+			}
+			fmt++;
+			continue;
+		}
+
+		CHECK_AND_PUT_CHAR(s, n, chars_printed, *fmt);
+
+		fmt++;
+	}
+
+	if (n > 0U) {
+		*s = '\0';
+	}
+
+	return (int)chars_printed;
+}
+
+/*******************************************************************
+ * Reduced snprintf to be used for Trusted firmware.
+ * The following type specifiers are supported:
+ *
+ * %x (or %X) - hexadecimal format
+ * %d or %i - signed decimal format
+ * %s - string format
+ * %u - unsigned decimal format
+ * %p - pointer format
+ *
+ * The following padding specifiers are supported by this print
+ * %0NN - Left-pad the number with 0s (NN is a decimal number)
+ * %NN - Left-pad the number or string with spaces (NN is a decimal number)
+ * %-NN - Right-pad the number or string with spaces (NN is a decimal number)
+ *
+ * The function panics on all other formats specifiers.
+ *
+ * It returns the number of characters that would be written if the
+ * buffer was big enough. If it returns a value lower than n, the
+ * whole string has been written.
+ *******************************************************************/
+int snprintf(char *s, size_t n, const char *fmt, ...)
+{
+	int count;
+	va_list all_args;
+
+	va_start(all_args, fmt);
+	count = vsnprintf(s, n, fmt, all_args);
+	va_end(all_args);
+
+	return count;
+}
diff --git a/components/common/libc/src/strchr.c b/components/common/libc/src/strchr.c
new file mode 100644
index 0000000..1cd03ca
--- /dev/null
+++ b/components/common/libc/src/strchr.c
@@ -0,0 +1,53 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+char *
+strchr(const char *p, int ch)
+{
+	char c;
+
+	c = ch;
+	for (;; ++p) {
+		if (*p == c)
+			return ((char *)p);
+		if (*p == '\0')
+			return (NULL);
+	}
+	/* NOTREACHED */
+}
diff --git a/components/common/libc/src/strcmp.c b/components/common/libc/src/strcmp.c
new file mode 100644
index 0000000..290db4c
--- /dev/null
+++ b/components/common/libc/src/strcmp.c
@@ -0,0 +1,52 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#include <string.h>
+
+/*
+ * Compare strings.
+ */
+int
+strcmp(const char *s1, const char *s2)
+{
+	while (*s1 == *s2++)
+		if (*s1++ == '\0')
+			return (0);
+	return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
+}
diff --git a/components/common/libc/src/strcpy.c b/components/common/libc/src/strcpy.c
new file mode 100644
index 0000000..3ce5ec5
--- /dev/null
+++ b/components/common/libc/src/strcpy.c
@@ -0,0 +1,37 @@
+/*	$OpenBSD: strcpy.c,v 1.8 2005/08/08 08:05:37 espie Exp $	*/
+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <string.h>
+char *
+strcpy(char *to, const char *from)
+{
+	char *save = to;
+	for (; (*to = *from) != '\0'; ++from, ++to);
+	return(save);
+}
diff --git a/components/common/libc/src/strlcat.c b/components/common/libc/src/strlcat.c
new file mode 100644
index 0000000..e60c863
--- /dev/null
+++ b/components/common/libc/src/strlcat.c
@@ -0,0 +1,56 @@
+/*	$OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $	*/
+
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <string.h>
+
+/*
+ * Appends src to string dst of size dsize (unlike strncat, dsize is the
+ * full size of dst, not space left).  At most dsize-1 characters
+ * will be copied.  Always NUL terminates (unless dsize <= strlen(dst)).
+ * Returns strlen(src) + MIN(dsize, strlen(initial dst)).
+ * If retval >= dsize, truncation occurred.
+ */
+size_t
+strlcat(char * dst, const char * src, size_t dsize)
+{
+	const char *odst = dst;
+	const char *osrc = src;
+	size_t n = dsize;
+	size_t dlen;
+
+	/* Find the end of dst and adjust bytes left but don't go past end. */
+	while (n-- != 0 && *dst != '\0')
+		dst++;
+	dlen = dst - odst;
+	n = dsize - dlen;
+
+	if (n-- == 0)
+		return(dlen + strlen(src));
+	while (*src != '\0') {
+		if (n != 0) {
+			*dst++ = *src;
+			n--;
+		}
+		src++;
+	}
+	*dst = '\0';
+
+	return(dlen + (src - osrc));	/* count does not include NUL */
+}
diff --git a/components/common/libc/src/strlcpy.c b/components/common/libc/src/strlcpy.c
new file mode 100644
index 0000000..c4f39bb
--- /dev/null
+++ b/components/common/libc/src/strlcpy.c
@@ -0,0 +1,52 @@
+/*	$OpenBSD: strlcpy.c,v 1.12 2015/01/15 03:54:12 millert Exp $	*/
+
+/*
+ * SPDX-License-Identifier: ISC
+ *
+ * Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+/*
+ * Copy string src to buffer dst of size dsize.  At most dsize-1
+ * chars will be copied.  Always NUL terminates (unless dsize == 0).
+ * Returns strlen(src); if retval >= dsize, truncation occurred.
+ */
+size_t
+strlcpy(char * dst, const char * src, size_t dsize)
+{
+	const char *osrc = src;
+	size_t nleft = dsize;
+
+	/* Copy as many bytes as will fit. */
+	if (nleft != 0) {
+		while (--nleft != 0) {
+			if ((*dst++ = *src++) == '\0')
+				break;
+		}
+	}
+
+	/* Not enough room in dst, add NUL and traverse rest of src. */
+	if (nleft == 0) {
+		if (dsize != 0)
+			*dst = '\0';		/* NUL-terminate dst */
+		while (*src++)
+			;
+	}
+
+	return(src - osrc - 1);	/* count does not include NUL */
+}
diff --git a/components/common/libc/src/strlen.c b/components/common/libc/src/strlen.c
new file mode 100644
index 0000000..e4b79d9
--- /dev/null
+++ b/components/common/libc/src/strlen.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+
+size_t strlen(const char *s)
+{
+	const char *cursor = s;
+
+	while (*cursor)
+		cursor++;
+
+	return cursor - s;
+}
diff --git a/components/common/libc/src/strncmp.c b/components/common/libc/src/strncmp.c
new file mode 100644
index 0000000..f0bbadc
--- /dev/null
+++ b/components/common/libc/src/strncmp.c
@@ -0,0 +1,53 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#include <string.h>
+
+int
+strncmp(const char *s1, const char *s2, size_t n)
+{
+
+	if (n == 0)
+		return (0);
+	do {
+		if (*s1 != *s2++)
+			return (*(const unsigned char *)s1 -
+				*(const unsigned char *)(s2 - 1));
+		if (*s1++ == '\0')
+			break;
+	} while (--n != 0);
+	return (0);
+}
diff --git a/components/common/libc/src/strnlen.c b/components/common/libc/src/strnlen.c
new file mode 100644
index 0000000..49e9f7a
--- /dev/null
+++ b/components/common/libc/src/strnlen.c
@@ -0,0 +1,46 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Portions copyright (c) 2018, Arm Limited and Contributors.
+ * All rights reserved.
+ */
+
+#include <string.h>
+
+size_t
+strnlen(const char *s, size_t maxlen)
+{
+	size_t len;
+
+	for (len = 0; len < maxlen; len++, s++) {
+		if (!*s)
+			break;
+	}
+	return (len);
+}
diff --git a/components/common/libc/src/strrchr.c b/components/common/libc/src/strrchr.c
new file mode 100644
index 0000000..cd435ff
--- /dev/null
+++ b/components/common/libc/src/strrchr.c
@@ -0,0 +1,49 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+char *
+strrchr(const char *p, int ch)
+{
+	char *save;
+	char c;
+
+	c = ch;
+	for (save = NULL;; ++p) {
+		if (*p == c)
+			save = (char *)p;
+		if (*p == '\0')
+			return (save);
+	}
+	/* NOTREACHED */
+}
diff --git a/components/common/libc/src/strstr.c b/components/common/libc/src/strstr.c
new file mode 100644
index 0000000..0192d0f
--- /dev/null
+++ b/components/common/libc/src/strstr.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+char *strstr(const char *haystack, const char *needle)
+{
+	const char *h = NULL;
+	size_t needle_len = 0;
+
+	if (needle[0] == '\0')
+		return (char *)haystack;
+
+	needle_len = strlen(needle);
+	for (h = haystack; (h = strchr(h, needle[0])) != 0; h++)
+		if (strncmp(h, needle, needle_len) == 0)
+			return (char *)h;
+
+	return NULL;
+}
diff --git a/components/common/libc/src/strtok.c b/components/common/libc/src/strtok.c
new file mode 100644
index 0000000..7e1a4d2
--- /dev/null
+++ b/components/common/libc/src/strtok.c
@@ -0,0 +1,83 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1998 Softweyr LLC.  All rights reserved.
+ *
+ * strtok_r, from Berkeley strtok
+ * Oct 13, 1998 by Wes Peters <wes@softweyr.com>
+ *
+ * Copyright (c) 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notices, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notices, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SOFTWEYR LLC, THE
+ * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+
+char *
+strtok_r(char *s, const char *delim, char **last)
+{
+	char *spanp, *tok;
+	int c, sc;
+
+	if (s == NULL && (s = *last) == NULL)
+		return (NULL);
+
+	/*
+	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
+	 */
+cont:
+	c = *s++;
+	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
+		if (c == sc)
+			goto cont;
+	}
+
+	if (c == 0) {		/* no non-delimiter characters */
+		*last = NULL;
+		return (NULL);
+	}
+	tok = s - 1;
+
+	/*
+	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
+	 * Note that delim must have one NUL; we stop if we see that, too.
+	 */
+	for (;;) {
+		c = *s++;
+		spanp = (char *)delim;
+		do {
+			if ((sc = *spanp++) == c) {
+				if (c == 0)
+					s = NULL;
+				else
+					s[-1] = '\0';
+				*last = s;
+				return (tok);
+			}
+		} while (sc != 0);
+	}
+	/* NOTREACHED */
+}
diff --git a/components/common/libc/src/strtol.c b/components/common/libc/src/strtol.c
new file mode 100644
index 0000000..deb862c
--- /dev/null
+++ b/components/common/libc/src/strtol.c
@@ -0,0 +1,133 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to a long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long strtol(const char *nptr, char **endptr, int base)
+{
+	const char *s;
+	unsigned long acc;
+	char c;
+	unsigned long cutoff;
+	int neg, any, cutlim;
+
+	/*
+	 * Skip white space and pick up leading +/- sign if any.
+	 * If base is 0, allow 0x for hex and 0 for octal, else
+	 * assume decimal; if base is already 16, allow 0x.
+	 */
+	s = nptr;
+	do {
+		c = *s++;
+	} while (isspace((unsigned char)c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X') &&
+	    ((s[1] >= '0' && s[1] <= '9') ||
+	    (s[1] >= 'A' && s[1] <= 'F') ||
+	    (s[1] >= 'a' && s[1] <= 'f'))) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	acc = any = 0;
+
+	/*
+	 * Compute the cutoff value between legal numbers and illegal
+	 * numbers.  That is the largest legal value, divided by the
+	 * base.  An input number that is greater than this value, if
+	 * followed by a legal input character, is too big.  One that
+	 * is equal to this value may be valid or not; the limit
+	 * between valid and invalid numbers is then based on the last
+	 * digit.  For instance, if the range for longs is
+	 * [-2147483648..2147483647] and the input base is 10,
+	 * cutoff will be set to 214748364 and cutlim to either
+	 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
+	 * a value > 214748364, or equal but the next digit is > 7 (or 8),
+	 * the number is too big, and we will return a range error.
+	 *
+	 * Set 'any' if any `digits' consumed; make it negative to indicate
+	 * overflow.
+	 */
+	cutoff = neg ? (unsigned long)-(LONG_MIN + LONG_MAX) + LONG_MAX
+	    : LONG_MAX;
+	cutlim = cutoff % base;
+	cutoff /= base;
+	for ( ; ; c = *s++) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'A' && c <= 'Z')
+			c -= 'A' - 10;
+		else if (c >= 'a' && c <= 'z')
+			c -= 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = neg ? LONG_MIN : LONG_MAX;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != NULL)
+		*endptr = (char *)(any ? s - 1 : nptr);
+	return (acc);
+}
diff --git a/components/common/libc/src/strtoll.c b/components/common/libc/src/strtoll.c
new file mode 100644
index 0000000..4e101e8
--- /dev/null
+++ b/components/common/libc/src/strtoll.c
@@ -0,0 +1,134 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to a long long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+long long strtoll(const char *nptr, char **endptr, int base)
+{
+	const char *s;
+	unsigned long long acc;
+	char c;
+	unsigned long long cutoff;
+	int neg, any, cutlim;
+
+	/*
+	 * Skip white space and pick up leading +/- sign if any.
+	 * If base is 0, allow 0x for hex and 0 for octal, else
+	 * assume decimal; if base is already 16, allow 0x.
+	 */
+	s = nptr;
+	do {
+		c = *s++;
+	} while (isspace((unsigned char)c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X') &&
+	    ((s[1] >= '0' && s[1] <= '9') ||
+	    (s[1] >= 'A' && s[1] <= 'F') ||
+	    (s[1] >= 'a' && s[1] <= 'f'))) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	acc = any = 0;
+
+	/*
+	 * Compute the cutoff value between legal numbers and illegal
+	 * numbers.  That is the largest legal value, divided by the
+	 * base.  An input number that is greater than this value, if
+	 * followed by a legal input character, is too big.  One that
+	 * is equal to this value may be valid or not; the limit
+	 * between valid and invalid numbers is then based on the last
+	 * digit.  For instance, if the range for quads is
+	 * [-9223372036854775808..9223372036854775807] and the input base
+	 * is 10, cutoff will be set to 922337203685477580 and cutlim to
+	 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
+	 * accumulated a value > 922337203685477580, or equal but the
+	 * next digit is > 7 (or 8), the number is too big, and we will
+	 * return a range error.
+	 *
+	 * Set 'any' if any `digits' consumed; make it negative to indicate
+	 * overflow.
+	 */
+	cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX
+	    : LLONG_MAX;
+	cutlim = cutoff % base;
+	cutoff /= base;
+	for ( ; ; c = *s++) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'A' && c <= 'Z')
+			c -= 'A' - 10;
+		else if (c >= 'a' && c <= 'z')
+			c -= 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = neg ? LLONG_MIN : LLONG_MAX;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != NULL)
+		*endptr = (char *)(any ? s - 1 : nptr);
+	return (acc);
+}
diff --git a/components/common/libc/src/strtoul.c b/components/common/libc/src/strtoul.c
new file mode 100644
index 0000000..b42fb14
--- /dev/null
+++ b/components/common/libc/src/strtoul.c
@@ -0,0 +1,112 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long strtoul(const char *nptr, char **endptr, int base)
+{
+	const char *s;
+	unsigned long acc;
+	char c;
+	unsigned long cutoff;
+	int neg, any, cutlim;
+
+	/*
+	 * See strtol for comments as to the logic used.
+	 */
+	s = nptr;
+	do {
+		c = *s++;
+	} while (isspace((unsigned char)c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X') &&
+	    ((s[1] >= '0' && s[1] <= '9') ||
+	    (s[1] >= 'A' && s[1] <= 'F') ||
+	    (s[1] >= 'a' && s[1] <= 'f'))) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	acc = any = 0;
+
+	cutoff = ULONG_MAX / base;
+	cutlim = ULONG_MAX % base;
+	for ( ; ; c = *s++) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'A' && c <= 'Z')
+			c -= 'A' - 10;
+		else if (c >= 'a' && c <= 'z')
+			c -= 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = ULONG_MAX;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != NULL)
+		*endptr = (char *)(any ? s - 1 : nptr);
+	return (acc);
+}
diff --git a/components/common/libc/src/strtoull.c b/components/common/libc/src/strtoull.c
new file mode 100644
index 0000000..2e65a43
--- /dev/null
+++ b/components/common/libc/src/strtoull.c
@@ -0,0 +1,112 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Copyright (c) 2011 The FreeBSD Foundation
+ * All rights reserved.
+ * Portions of this software were developed by David Chisnall
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+
+/*
+ * Convert a string to an unsigned long long integer.
+ *
+ * Assumes that the upper and lower case
+ * alphabets and digits are each contiguous.
+ */
+unsigned long long strtoull(const char *nptr, char **endptr, int base)
+{
+	const char *s;
+	unsigned long long acc;
+	char c;
+	unsigned long long cutoff;
+	int neg, any, cutlim;
+
+	/*
+	 * See strtoq for comments as to the logic used.
+	 */
+	s = nptr;
+	do {
+		c = *s++;
+	} while (isspace((unsigned char)c));
+	if (c == '-') {
+		neg = 1;
+		c = *s++;
+	} else {
+		neg = 0;
+		if (c == '+')
+			c = *s++;
+	}
+	if ((base == 0 || base == 16) &&
+	    c == '0' && (*s == 'x' || *s == 'X') &&
+	    ((s[1] >= '0' && s[1] <= '9') ||
+	    (s[1] >= 'A' && s[1] <= 'F') ||
+	    (s[1] >= 'a' && s[1] <= 'f'))) {
+		c = s[1];
+		s += 2;
+		base = 16;
+	}
+	if (base == 0)
+		base = c == '0' ? 8 : 10;
+	acc = any = 0;
+
+	cutoff = ULLONG_MAX / base;
+	cutlim = ULLONG_MAX % base;
+	for ( ; ; c = *s++) {
+		if (c >= '0' && c <= '9')
+			c -= '0';
+		else if (c >= 'A' && c <= 'Z')
+			c -= 'A' - 10;
+		else if (c >= 'a' && c <= 'z')
+			c -= 'a' - 10;
+		else
+			break;
+		if (c >= base)
+			break;
+		if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
+			any = -1;
+		else {
+			any = 1;
+			acc *= base;
+			acc += c;
+		}
+	}
+	if (any < 0) {
+		acc = ULLONG_MAX;
+	} else if (neg)
+		acc = -acc;
+	if (endptr != NULL)
+		*endptr = (char *)(any ? s - 1 : nptr);
+	return (acc);
+}
diff --git a/components/common/libpsats/component.cmake b/components/common/libpsats/component.cmake
new file mode 100644
index 0000000..e1ea32d
--- /dev/null
+++ b/components/common/libpsats/component.cmake
@@ -0,0 +1,16 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/libpsats-attestation.c"
+	"${CMAKE_CURRENT_LIST_DIR}/libpsats-crypto.c"
+	"${CMAKE_CURRENT_LIST_DIR}/libpsats-its.c"
+	"${CMAKE_CURRENT_LIST_DIR}/libpsats-ps.c"
+	)
diff --git a/components/common/libpsats/libpsats-attestation.c b/components/common/libpsats/libpsats-attestation.c
new file mode 100644
index 0000000..c67422b
--- /dev/null
+++ b/components/common/libpsats/libpsats-attestation.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <psa/initial_attestation.h>
+#include <service/attestation/client/provision/attest_provision_client.h>
+#include <service/attestation/client/psa/iat_client.h>
+#include <service_locator.h>
+#include <stdio.h>
+
+#include "libpsats.h"
+#include "trace.h"
+
+static struct rpc_caller_session *rpc_session;
+static struct service_context *attestation_service_context;
+
+LIBPSATS_EXPORTED psa_status_t libpsats_init_attestation_context(const char *service_name)
+{
+	psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+	psa_status_t provision_result = PSA_ERROR_GENERIC_ERROR;
+
+	if (rpc_session || attestation_service_context) {
+		EMSG("The client is already initialized\n");
+		return result;
+	}
+
+	service_locator_init();
+
+	attestation_service_context = service_locator_query(service_name);
+
+	if (!attestation_service_context) {
+		EMSG("Failed to discover service\n");
+		return result;
+	}
+
+	rpc_session = service_context_open(attestation_service_context);
+
+	if (!rpc_session) {
+		EMSG("Failed to open rpc session\n");
+		libpsats_deinit_attestation_context();
+		return result;
+	}
+
+	result = psa_iat_client_init(rpc_session);
+
+	if (result) {
+		EMSG("psa_iat_client_init failed\n");
+		return result;
+	}
+
+	provision_result = attest_provision_client_init(rpc_session);
+
+	/* If external IAK is used this call can fail */
+	if (provision_result)
+		EMSG(
+			"attest_provision_client_init failed. Are you using external IAK key?\n");
+
+	return result;
+}
+
+LIBPSATS_EXPORTED void libpsats_deinit_attestation_context(void)
+{
+	psa_iat_client_deinit();
+	attest_provision_client_deinit();
+
+	if (attestation_service_context && rpc_session) {
+		service_context_close(attestation_service_context, rpc_session);
+		rpc_session = NULL;
+	}
+
+	if (attestation_service_context) {
+		service_context_relinquish(attestation_service_context);
+		attestation_service_context = NULL;
+	}
+}
diff --git a/components/common/libpsats/libpsats-crypto.c b/components/common/libpsats/libpsats-crypto.c
new file mode 100644
index 0000000..cb4b6f0
--- /dev/null
+++ b/components/common/libpsats/libpsats-crypto.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service/crypto/client/psa/psa_crypto_client.h>
+#include <service_locator.h>
+#include <stdio.h>
+
+#include "libpsats.h"
+#include "trace.h"
+
+static struct rpc_caller_session *rpc_session;
+static struct service_context *crypto_service_context;
+
+LIBPSATS_EXPORTED psa_status_t libpsats_init_crypto_context(const char *service_name)
+{
+	psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+
+	if (rpc_session || crypto_service_context) {
+		EMSG("The client is already initialized\n");
+		return result;
+	}
+
+	service_locator_init();
+
+	crypto_service_context = service_locator_query(service_name);
+
+	if (!crypto_service_context) {
+		EMSG("Failed to discover service\n");
+		return result;
+	}
+
+	rpc_session = service_context_open(crypto_service_context);
+
+	if (!rpc_session) {
+		EMSG("Failed to open rpc session\n");
+		libpsats_deinit_crypto_context();
+		return result;
+	}
+
+	result = psa_crypto_client_init(rpc_session);
+
+	if (result)
+		EMSG("psa_crypto_client_init failed\n");
+
+	return result;
+}
+
+LIBPSATS_EXPORTED void libpsats_deinit_crypto_context(void)
+{
+	psa_crypto_client_deinit();
+
+	if (crypto_service_context && rpc_session) {
+		service_context_close(crypto_service_context, rpc_session);
+		rpc_session = NULL;
+	}
+
+	if (crypto_service_context) {
+		service_context_relinquish(crypto_service_context);
+		crypto_service_context = NULL;
+	}
+}
diff --git a/components/common/libpsats/libpsats-its.c b/components/common/libpsats/libpsats-its.c
new file mode 100644
index 0000000..db98c1d
--- /dev/null
+++ b/components/common/libpsats/libpsats-its.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
+#include <service/secure_storage/frontend/psa/its/its_frontend.h>
+#include <service_locator.h>
+#include <stdio.h>
+
+#include "libpsats.h"
+#include "trace.h"
+
+static struct rpc_caller_session *rpc_session;
+static struct service_context *its_service_context;
+static struct secure_storage_client its_storage_client;
+
+LIBPSATS_EXPORTED psa_status_t libpsats_init_its_context(const char *service_name)
+{
+	psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+
+	if (rpc_session || its_service_context) {
+		EMSG("The client is already initialized\n");
+		return result;
+	}
+
+	service_locator_init();
+
+	its_service_context = service_locator_query(service_name);
+
+	if (!its_service_context) {
+		EMSG("Failed to discover service\n");
+		return result;
+	}
+
+	rpc_session = service_context_open(its_service_context);
+
+	if (!rpc_session) {
+		EMSG("Failed to open rpc session\n");
+		libpsats_deinit_its_context();
+		return result;
+	}
+
+	struct storage_backend *its_storage_backend =
+		secure_storage_client_init(&its_storage_client, rpc_session);
+
+	if (!its_storage_backend) {
+		EMSG("Failed to initialize storage backend\n");
+		libpsats_deinit_its_context();
+		return result;
+	}
+
+	result = psa_its_frontend_init(its_storage_backend);
+
+	return result;
+}
+
+LIBPSATS_EXPORTED void libpsats_deinit_its_context(void)
+{
+	psa_its_frontend_init(NULL);
+	secure_storage_client_deinit(&its_storage_client);
+
+	if (its_service_context && rpc_session) {
+		service_context_close(its_service_context, rpc_session);
+		rpc_session = NULL;
+	}
+
+	if (its_service_context) {
+		service_context_relinquish(its_service_context);
+		its_service_context = NULL;
+	}
+}
diff --git a/components/common/libpsats/libpsats-ps.c b/components/common/libpsats/libpsats-ps.c
new file mode 100644
index 0000000..a776460
--- /dev/null
+++ b/components/common/libpsats/libpsats-ps.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <protocols/rpc/common/packed-c/encoding.h>
+#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
+#include <service/secure_storage/frontend/psa/ps/ps_frontend.h>
+#include <service_locator.h>
+#include <stdio.h>
+
+#include "libpsats.h"
+#include "trace.h"
+
+static struct rpc_caller_session *rpc_session;
+static struct service_context *ps_service_context;
+static struct secure_storage_client ps_storage_client;
+
+LIBPSATS_EXPORTED psa_status_t libpsats_init_ps_context(const char *service_name)
+{
+	psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+
+	if (rpc_session || ps_service_context) {
+		EMSG("The client is already initialized\n");
+		return result;
+	}
+
+	service_locator_init();
+
+	ps_service_context = service_locator_query(service_name);
+
+	if (!ps_service_context) {
+		EMSG("Failed to discover service\n");
+		return result;
+	}
+
+	rpc_session = service_context_open(ps_service_context);
+
+	if (!rpc_session) {
+		EMSG("Failed to open rpc session\n");
+		libpsats_deinit_ps_context();
+		return result;
+	}
+
+	struct storage_backend *ps_storage_backend =
+		secure_storage_client_init(&ps_storage_client, rpc_session);
+
+	if (!ps_storage_backend) {
+		EMSG("Failed to initialize storage backend\n");
+		libpsats_deinit_ps_context();
+		return result;
+	}
+
+	result = psa_ps_frontend_init(ps_storage_backend);
+
+	return result;
+}
+
+LIBPSATS_EXPORTED void libpsats_deinit_ps_context(void)
+{
+	psa_ps_frontend_init(NULL);
+	secure_storage_client_deinit(&ps_storage_client);
+
+	if (ps_service_context && rpc_session) {
+		service_context_close(ps_service_context, rpc_session);
+		rpc_session = NULL;
+	}
+
+	if (ps_service_context) {
+		service_context_relinquish(ps_service_context);
+		ps_service_context = NULL;
+	}
+}
diff --git a/components/common/libpsats/libpsats.h b/components/common/libpsats/libpsats.h
new file mode 100644
index 0000000..b4ca9ca
--- /dev/null
+++ b/components/common/libpsats/libpsats.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "psa/crypto_types.h"
+#include "psa/initial_attestation.h"
+#include "psa/internal_trusted_storage.h"
+#include "psa/protected_storage.h"
+
+#ifndef LIBPSATS_H
+#define LIBPSATS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The functions may be exported as a public interface to
+ * a shared library.
+ */
+#ifdef EXPORT_PUBLIC_INTERFACE_LIBPSATS
+#define LIBPSATS_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define LIBPSATS_EXPORTED
+#endif
+
+LIBPSATS_EXPORTED psa_status_t libpsats_init_crypto_context(const char *service_name);
+LIBPSATS_EXPORTED void libpsats_deinit_crypto_context(void);
+
+LIBPSATS_EXPORTED psa_status_t libpsats_init_attestation_context(const char *service_name);
+LIBPSATS_EXPORTED void libpsats_deinit_attestation_context(void);
+
+LIBPSATS_EXPORTED psa_status_t libpsats_init_its_context(const char *service_name);
+LIBPSATS_EXPORTED void libpsats_deinit_its_context(void);
+
+LIBPSATS_EXPORTED psa_status_t libpsats_init_ps_context(const char *service_name);
+LIBPSATS_EXPORTED void libpsats_deinit_ps_context(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LIBPSATS_H */
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/common/mbedtls/component.cmake
similarity index 72%
copy from components/service/fwu/provider/serializer/packed-c/component.cmake
copy to components/common/mbedtls/component.cmake
index 4209cae..e04a42f 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/common/mbedtls/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
-	)
+	"${CMAKE_CURRENT_LIST_DIR}/mbedtls_utils.c"
+)
diff --git a/components/common/mbedtls/mbedtls_utils.c b/components/common/mbedtls/mbedtls_utils.c
new file mode 100644
index 0000000..e7c97e9
--- /dev/null
+++ b/components/common/mbedtls/mbedtls_utils.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include "mbedtls_utils.h"
+
+/*
+ * Official value: http://www.oid-info.com/get/2.5.4.3
+ * Hex converter: https://misc.daniel-marschall.de/asn.1/oid-converter/online.php
+ */
+#define CN_OID_TAG (0x06)
+#define CN_OID_LEN (0x03)
+#define CN_OID_VAL {0x55, 0x04, 0x03}
+
+/* Searches for the common name field in an mbedtls_asn1_named_data object */
+const mbedtls_asn1_buf* findCommonName(const mbedtls_asn1_named_data *name)
+{
+	static const uint8_t cn_oid_values[CN_OID_LEN] = CN_OID_VAL;
+
+	while (name)
+	{
+		if (name->oid.tag == CN_OID_TAG && name->oid.len == CN_OID_LEN) {
+			if (name->oid.p != NULL) {
+				if (!memcmp(name->oid.p, cn_oid_values, (size_t) CN_OID_LEN))
+					return &name->val;
+			}
+		}
+
+		name = name->next;
+	}
+
+	return NULL;
+}
diff --git a/components/common/mbedtls/mbedtls_utils.h b/components/common/mbedtls/mbedtls_utils.h
new file mode 100644
index 0000000..0e2f396
--- /dev/null
+++ b/components/common/mbedtls/mbedtls_utils.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MBEDTLS_UTILS_H
+#define MBEDTLS_UTILS_H
+
+#include <mbedtls/asn1.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const mbedtls_asn1_buf* findCommonName(const mbedtls_asn1_named_data *name);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MBEDTLS_UTILS_H */
diff --git a/components/common/trace/component.cmake b/components/common/trace/component.cmake
index c591832..9964c84 100644
--- a/components/common/trace/component.cmake
+++ b/components/common/trace/component.cmake
@@ -12,7 +12,8 @@
 
 target_include_directories(${TGT}
 	PUBLIC
-		"${CMAKE_CURRENT_LIST_DIR}/include"
+		$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+		$<INSTALL_INTERFACE:${TS_ENV}/include>
 	)
 
 target_sources(${TGT} PRIVATE
diff --git a/components/common/trace/include/trace.h b/components/common/trace/include/trace.h
index d9b6c07..7e2e561 100644
--- a/components/common/trace/include/trace.h
+++ b/components/common/trace/include/trace.h
@@ -8,46 +8,53 @@
 
 #include "compiler.h"
 
+#ifdef EXPORT_PUBLIC_INTERFACE_TRACE
+#define TRACE_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define TRACE_EXPORTED
+#endif
+
 #define TRACE_LEVEL_NONE	(0)
 #define TRACE_LEVEL_ERROR	(1)
 #define TRACE_LEVEL_INFO	(2)
 #define TRACE_LEVEL_DEBUG	(3)
 
 #ifndef TRACE_LEVEL
-#define TRACE_LEVEL	TRACE_LEVEL_ERROR
+#error "Trace level is not defined!"
 #endif /* TRACE_LEVEL */
 
 /**
- * no_trace_printf will be optimized out becase of the 'if (0)' but all the
+ * no_ts_trace_printf will be optimized out becase of the 'if (0)' but all the
  * checks will still run against the format string and the parameters.
  */
-#define no_trace_printf(func, line, level, fmt, ...)				\
+#define no_ts_trace_printf(func, line, level, fmt, ...)				\
 	do {									\
 		if (0) {							\
-			trace_printf(func, line, level, fmt, ##__VA_ARGS__);	\
+			ts_trace_printf(func, line, level, fmt, ##__VA_ARGS__);	\
 		}								\
 	} while (0)
 
 extern void (*trace_puts_interface)(const char *str);
 void trace_puts(const char *str);
-void trace_printf(const char *func, int line, int level, const char *fmt, ...) __printf(4, 5);
+TRACE_EXPORTED
+void ts_trace_printf(const char *func, int line, int level, const char *fmt, ...) __printf(4, 5);
 
 #if TRACE_LEVEL >= TRACE_LEVEL_ERROR
-#define EMSG(...)	trace_printf(__func__, __LINE__, TRACE_LEVEL_ERROR, __VA_ARGS__)
+#define EMSG(...)	ts_trace_printf(__func__, __LINE__, TRACE_LEVEL_ERROR, __VA_ARGS__)
 #else
-#define EMSG(...)	no_trace_printf(__func__, __LINE__, TRACE_LEVEL_ERROR, __VA_ARGS__)
+#define EMSG(...)	no_ts_trace_printf(__func__, __LINE__, TRACE_LEVEL_ERROR, __VA_ARGS__)
 #endif /* TRACE_LEVEL >= TRACE_LEVEL_ERROR */
 
 #if TRACE_LEVEL >= TRACE_LEVEL_INFO
-#define IMSG(...)	trace_printf(__func__, __LINE__, TRACE_LEVEL_INFO, __VA_ARGS__)
+#define IMSG(...)	ts_trace_printf(__func__, __LINE__, TRACE_LEVEL_INFO, __VA_ARGS__)
 #else
-#define IMSG(...)	no_trace_printf(__func__, __LINE__, TRACE_LEVEL_INFO, __VA_ARGS__)
+#define IMSG(...)	no_ts_trace_printf(__func__, __LINE__, TRACE_LEVEL_INFO, __VA_ARGS__)
 #endif /* TRACE_LEVEL >= TRACE_LEVEL_INFO */
 
 #if TRACE_LEVEL >= TRACE_LEVEL_DEBUG
-#define DMSG(...)	trace_printf(__func__, __LINE__, TRACE_LEVEL_DEBUG, __VA_ARGS__)
+#define DMSG(...)	ts_trace_printf(__func__, __LINE__, TRACE_LEVEL_DEBUG, __VA_ARGS__)
 #else
-#define DMSG(...)	no_trace_printf(__func__, __LINE__, TRACE_LEVEL_DEBUG, __VA_ARGS__)
+#define DMSG(...)	no_ts_trace_printf(__func__, __LINE__, TRACE_LEVEL_DEBUG, __VA_ARGS__)
 #endif /* TRACE_LEVEL >= TRACE_LEVEL_DEBUG */
 
 #endif /* TRACE_H_ */
diff --git a/components/common/trace/trace.c b/components/common/trace/trace.c
index 372226b..728257f 100644
--- a/components/common/trace/trace.c
+++ b/components/common/trace/trace.c
@@ -14,7 +14,7 @@
 
 void (*trace_puts_interface)(const char *str) = &trace_puts;
 
-void trace_printf(const char *func, int line, int level, const char *fmt, ...)
+void ts_trace_printf(const char *func, int line, int level, const char *fmt, ...)
 {
 	char buffer[256];
 	char level_char = 0;
diff --git a/components/common/utils/include/arm64_bti.S b/components/common/utils/include/arm64_bti.S
new file mode 100644
index 0000000..63f42c7
--- /dev/null
+++ b/components/common/utils/include/arm64_bti.S
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * Copyright (c) 2021, Linaro Limited
+ */
+
+#include <elf_common.h>
+
+/*
+ * This macro emits a program property note section identifying
+ * architecture features which require special handling, mainly for
+ * use in assembly files in the libraries linked with TA's.
+ */
+
+.macro emit_aarch64_feature_1_and, feat
+	.pushsection .note.gnu.property, "a"
+	.align  3
+	.long   2f - 1f				/* n_namesz */
+	.long   6f - 3f				/* n_desc_sz */
+	.long   NT_GNU_PROPERTY_TYPE_0		/* n_type */
+1:      .string "GNU"				/* name */
+2:
+	.align  3
+3:      .long   GNU_PROPERTY_AARCH64_FEATURE_1_AND 	/* pr_type */
+	.long   5f - 4f					/* pr_datasz */
+4:
+	/*
+	 * This is described with an array of char in the Linux API
+	 * spec but the text and all other usage (including binutils,
+	 * clang and GCC) treat this as a 32 bit value so no swizzling
+	 * is required for big endian.
+	 */
+	.long   \feat					/* property */
+5:
+	.align  3
+6:
+	.popsection
+.endm
diff --git a/components/common/utils/include/asm.S b/components/common/utils/include/asm.S
index d3cecc3..9ed065f 100644
--- a/components/common/utils/include/asm.S
+++ b/components/common/utils/include/asm.S
@@ -1,8 +1,17 @@
 /* SPDX-License-Identifier: BSD-2-Clause */
 /*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
  * Copyright (c) 2014, STMicroelectronics International N.V.
  */
 
+#if defined(BTI_ENABLED)
+#include <arm64_bti.S>
+
+#define BTI(...) __VA_ARGS__
+#else
+#define BTI(...)
+#endif
+
 	.macro FUNC name colon section=default
 	.ifc	\section\(),default
 	.section .text.\name
@@ -13,6 +22,7 @@
 	.type \name , %function
 	.balign 4
 	\name \colon
+	BTI(bti c)
 	.endm
 
 	.macro DATA name colon
@@ -30,6 +40,7 @@
 	.type \name , %function
 	.balign 4
 	\name \colon
+	BTI(bti c)
 	.endm
 
 	.macro LOCAL_DATA name colon
diff --git a/components/common/utils/include/compiler.h b/components/common/utils/include/compiler.h
index 075530b..185872e 100644
--- a/components/common/utils/include/compiler.h
+++ b/components/common/utils/include/compiler.h
@@ -1,7 +1,7 @@
 /* SPDX-License-Identifier: BSD-2-Clause */
 /*
  * Copyright (c) 2014, STMicroelectronics International N.V.
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  */
 
 #ifndef COMPILER_H
@@ -14,7 +14,7 @@
  * definitive owner and thus solves the problem.
  */
 #ifdef ENABLE_CDEFSH_FIX
-#include <sys/cdefs.h>
+#include <cdefs.h>
 #endif
 
 /*
@@ -56,7 +56,9 @@
 #ifndef __unused
 #define __unused	__attribute__((unused))
 #endif
+#ifndef __maybe_unused
 #define __maybe_unused	__attribute__((unused))
+#endif
 #ifndef __used
 #define __used		__attribute__((__used__))
 #endif
diff --git a/components/common/utils/include/elf_common.h b/components/common/utils/include/elf_common.h
new file mode 100644
index 0000000..a2bf375
--- /dev/null
+++ b/components/common/utils/include/elf_common.h
@@ -0,0 +1,1061 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*-
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2000, 2001, 2008, 2011, David E. O'Brien
+ * Copyright (c) 1998 John D. Polstra.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _SYS_ELF_COMMON_H_
+#define	_SYS_ELF_COMMON_H_ 1
+
+/*
+ * ELF definitions that are independent of architecture or word size.
+ */
+
+#ifndef __ASSEMBLER__
+
+#include <stdint.h>
+
+/*
+ * Note header.  The ".note" section contains an array of notes.  Each
+ * begins with this header, aligned to a word boundary.  Immediately
+ * following the note header is n_namesz bytes of name, padded to the
+ * next word boundary.  Then comes n_descsz bytes of descriptor, again
+ * padded to a word boundary.  The values of n_namesz and n_descsz do
+ * not include the padding.
+ */
+
+typedef struct {
+	uint32_t	n_namesz;	/* Length of name. */
+	uint32_t	n_descsz;	/* Length of descriptor. */
+	uint32_t	n_type;		/* Type of this note. */
+} Elf_Note;
+
+/*
+ * The header for GNU-style hash sections.
+ */
+
+typedef struct {
+	uint32_t	gh_nbuckets;	/* Number of hash buckets. */
+	uint32_t	gh_symndx;	/* First visible symbol in .dynsym. */
+	uint32_t	gh_maskwords;	/* #maskwords used in bloom filter. */
+	uint32_t	gh_shift2;	/* Bloom filter shift count. */
+} Elf_GNU_Hash_Header;
+
+/*
+ * Program Property Array
+ */
+typedef struct {
+	uint32_t	pr_type;
+	uint32_t	pr_datasz;
+} Elf_Prop;
+#endif /*__ASSEMBLER__*/
+
+/* Indexes into the e_ident array.  Keep synced with
+   http://www.sco.com/developers/gabi/latest/ch4.eheader.html */
+#define	EI_MAG0		0	/* Magic number, byte 0. */
+#define	EI_MAG1		1	/* Magic number, byte 1. */
+#define	EI_MAG2		2	/* Magic number, byte 2. */
+#define	EI_MAG3		3	/* Magic number, byte 3. */
+#define	EI_CLASS	4	/* Class of machine. */
+#define	EI_DATA		5	/* Data format. */
+#define	EI_VERSION	6	/* ELF format version. */
+#define	EI_OSABI	7	/* Operating system / ABI identification */
+#define	EI_ABIVERSION	8	/* ABI version */
+#define	OLD_EI_BRAND	8	/* Start of architecture identification. */
+#define	EI_PAD		9	/* Start of padding (per SVR4 ABI). */
+#define	EI_NIDENT	16	/* Size of e_ident array. */
+
+/* Values for the magic number bytes. */
+#define	ELFMAG0		0x7f
+#define	ELFMAG1		'E'
+#define	ELFMAG2		'L'
+#define	ELFMAG3		'F'
+#define	ELFMAG		"\177ELF"	/* magic string */
+#define	SELFMAG		4		/* magic string size */
+
+/* Values for e_ident[EI_VERSION] and e_version. */
+#define	EV_NONE		0
+#define	EV_CURRENT	1
+
+/* Values for e_ident[EI_CLASS]. */
+#define	ELFCLASSNONE	0	/* Unknown class. */
+#define	ELFCLASS32	1	/* 32-bit architecture. */
+#define	ELFCLASS64	2	/* 64-bit architecture. */
+
+/* Values for e_ident[EI_DATA]. */
+#define	ELFDATANONE	0	/* Unknown data format. */
+#define	ELFDATA2LSB	1	/* 2's complement little-endian. */
+#define	ELFDATA2MSB	2	/* 2's complement big-endian. */
+
+/* Values for e_ident[EI_OSABI]. */
+#define	ELFOSABI_NONE		0	/* UNIX System V ABI */
+#define	ELFOSABI_HPUX		1	/* HP-UX operating system */
+#define	ELFOSABI_NETBSD		2	/* NetBSD */
+#define	ELFOSABI_LINUX		3	/* GNU/Linux */
+#define	ELFOSABI_HURD		4	/* GNU/Hurd */
+#define	ELFOSABI_86OPEN		5	/* 86Open common IA32 ABI */
+#define	ELFOSABI_SOLARIS	6	/* Solaris */
+#define	ELFOSABI_AIX		7	/* AIX */
+#define	ELFOSABI_IRIX		8	/* IRIX */
+#define	ELFOSABI_FREEBSD	9	/* FreeBSD */
+#define	ELFOSABI_TRU64		10	/* TRU64 UNIX */
+#define	ELFOSABI_MODESTO	11	/* Novell Modesto */
+#define	ELFOSABI_OPENBSD	12	/* OpenBSD */
+#define	ELFOSABI_OPENVMS	13	/* Open VMS */
+#define	ELFOSABI_NSK		14	/* HP Non-Stop Kernel */
+#define	ELFOSABI_AROS		15	/* Amiga Research OS */
+#define	ELFOSABI_ARM		97	/* ARM */
+#define	ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
+
+#define	ELFOSABI_SYSV		ELFOSABI_NONE	/* symbol used in old spec */
+#define	ELFOSABI_MONTEREY	ELFOSABI_AIX	/* Monterey */
+
+/* e_ident */
+#define	IS_ELF(ehdr)	((ehdr).e_ident[EI_MAG0] == ELFMAG0 && \
+			 (ehdr).e_ident[EI_MAG1] == ELFMAG1 && \
+			 (ehdr).e_ident[EI_MAG2] == ELFMAG2 && \
+			 (ehdr).e_ident[EI_MAG3] == ELFMAG3)
+
+/* Values for e_type. */
+#define	ET_NONE		0	/* Unknown type. */
+#define	ET_REL		1	/* Relocatable. */
+#define	ET_EXEC		2	/* Executable. */
+#define	ET_DYN		3	/* Shared object. */
+#define	ET_CORE		4	/* Core file. */
+#define	ET_LOOS		0xfe00	/* First operating system specific. */
+#define	ET_HIOS		0xfeff	/* Last operating system-specific. */
+#define	ET_LOPROC	0xff00	/* First processor-specific. */
+#define	ET_HIPROC	0xffff	/* Last processor-specific. */
+
+/* Values for e_machine. */
+#define	EM_NONE		0	/* Unknown machine. */
+#define	EM_M32		1	/* AT&T WE32100. */
+#define	EM_SPARC	2	/* Sun SPARC. */
+#define	EM_386		3	/* Intel i386. */
+#define	EM_68K		4	/* Motorola 68000. */
+#define	EM_88K		5	/* Motorola 88000. */
+#define	EM_860		7	/* Intel i860. */
+#define	EM_MIPS		8	/* MIPS R3000 Big-Endian only. */
+#define	EM_S370		9	/* IBM System/370. */
+#define	EM_MIPS_RS3_LE	10	/* MIPS R3000 Little-Endian. */
+#define	EM_PARISC	15	/* HP PA-RISC. */
+#define	EM_VPP500	17	/* Fujitsu VPP500. */
+#define	EM_SPARC32PLUS	18	/* SPARC v8plus. */
+#define	EM_960		19	/* Intel 80960. */
+#define	EM_PPC		20	/* PowerPC 32-bit. */
+#define	EM_PPC64	21	/* PowerPC 64-bit. */
+#define	EM_S390		22	/* IBM System/390. */
+#define	EM_V800		36	/* NEC V800. */
+#define	EM_FR20		37	/* Fujitsu FR20. */
+#define	EM_RH32		38	/* TRW RH-32. */
+#define	EM_RCE		39	/* Motorola RCE. */
+#define	EM_ARM		40	/* ARM. */
+#define	EM_SH		42	/* Hitachi SH. */
+#define	EM_SPARCV9	43	/* SPARC v9 64-bit. */
+#define	EM_TRICORE	44	/* Siemens TriCore embedded processor. */
+#define	EM_ARC		45	/* Argonaut RISC Core. */
+#define	EM_H8_300	46	/* Hitachi H8/300. */
+#define	EM_H8_300H	47	/* Hitachi H8/300H. */
+#define	EM_H8S		48	/* Hitachi H8S. */
+#define	EM_H8_500	49	/* Hitachi H8/500. */
+#define	EM_IA_64	50	/* Intel IA-64 Processor. */
+#define	EM_MIPS_X	51	/* Stanford MIPS-X. */
+#define	EM_COLDFIRE	52	/* Motorola ColdFire. */
+#define	EM_68HC12	53	/* Motorola M68HC12. */
+#define	EM_MMA		54	/* Fujitsu MMA. */
+#define	EM_PCP		55	/* Siemens PCP. */
+#define	EM_NCPU		56	/* Sony nCPU. */
+#define	EM_NDR1		57	/* Denso NDR1 microprocessor. */
+#define	EM_STARCORE	58	/* Motorola Star*Core processor. */
+#define	EM_ME16		59	/* Toyota ME16 processor. */
+#define	EM_ST100	60	/* STMicroelectronics ST100 processor. */
+#define	EM_TINYJ	61	/* Advanced Logic Corp. TinyJ processor. */
+#define	EM_X86_64	62	/* Advanced Micro Devices x86-64 */
+#define	EM_AMD64	EM_X86_64	/* Advanced Micro Devices x86-64 (compat) */
+#define	EM_PDSP		63	/* Sony DSP Processor. */
+#define	EM_FX66		66	/* Siemens FX66 microcontroller. */
+#define	EM_ST9PLUS	67	/* STMicroelectronics ST9+ 8/16
+				   microcontroller. */
+#define	EM_ST7		68	/* STmicroelectronics ST7 8-bit
+				   microcontroller. */
+#define	EM_68HC16	69	/* Motorola MC68HC16 microcontroller. */
+#define	EM_68HC11	70	/* Motorola MC68HC11 microcontroller. */
+#define	EM_68HC08	71	/* Motorola MC68HC08 microcontroller. */
+#define	EM_68HC05	72	/* Motorola MC68HC05 microcontroller. */
+#define	EM_SVX		73	/* Silicon Graphics SVx. */
+#define	EM_ST19		74	/* STMicroelectronics ST19 8-bit mc. */
+#define	EM_VAX		75	/* Digital VAX. */
+#define	EM_CRIS		76	/* Axis Communications 32-bit embedded
+				   processor. */
+#define	EM_JAVELIN	77	/* Infineon Technologies 32-bit embedded
+				   processor. */
+#define	EM_FIREPATH	78	/* Element 14 64-bit DSP Processor. */
+#define	EM_ZSP		79	/* LSI Logic 16-bit DSP Processor. */
+#define	EM_MMIX		80	/* Donald Knuth's educational 64-bit proc. */
+#define	EM_HUANY	81	/* Harvard University machine-independent
+				   object files. */
+#define	EM_PRISM	82	/* SiTera Prism. */
+#define	EM_AVR		83	/* Atmel AVR 8-bit microcontroller. */
+#define	EM_FR30		84	/* Fujitsu FR30. */
+#define	EM_D10V		85	/* Mitsubishi D10V. */
+#define	EM_D30V		86	/* Mitsubishi D30V. */
+#define	EM_V850		87	/* NEC v850. */
+#define	EM_M32R		88	/* Mitsubishi M32R. */
+#define	EM_MN10300	89	/* Matsushita MN10300. */
+#define	EM_MN10200	90	/* Matsushita MN10200. */
+#define	EM_PJ		91	/* picoJava. */
+#define	EM_OPENRISC	92	/* OpenRISC 32-bit embedded processor. */
+#define	EM_ARC_A5	93	/* ARC Cores Tangent-A5. */
+#define	EM_XTENSA	94	/* Tensilica Xtensa Architecture. */
+#define	EM_VIDEOCORE	95	/* Alphamosaic VideoCore processor. */
+#define	EM_TMM_GPP	96	/* Thompson Multimedia General Purpose
+				   Processor. */
+#define	EM_NS32K	97	/* National Semiconductor 32000 series. */
+#define	EM_TPC		98	/* Tenor Network TPC processor. */
+#define	EM_SNP1K	99	/* Trebia SNP 1000 processor. */
+#define	EM_ST200	100	/* STMicroelectronics ST200 microcontroller. */
+#define	EM_IP2K		101	/* Ubicom IP2xxx microcontroller family. */
+#define	EM_MAX		102	/* MAX Processor. */
+#define	EM_CR		103	/* National Semiconductor CompactRISC
+				   microprocessor. */
+#define	EM_F2MC16	104	/* Fujitsu F2MC16. */
+#define	EM_MSP430	105	/* Texas Instruments embedded microcontroller
+				   msp430. */
+#define	EM_BLACKFIN	106	/* Analog Devices Blackfin (DSP) processor. */
+#define	EM_SE_C33	107	/* S1C33 Family of Seiko Epson processors. */
+#define	EM_SEP		108	/* Sharp embedded microprocessor. */
+#define	EM_ARCA		109	/* Arca RISC Microprocessor. */
+#define	EM_UNICORE	110	/* Microprocessor series from PKU-Unity Ltd.
+				   and MPRC of Peking University */
+#define	EM_AARCH64	183	/* AArch64 (64-bit ARM) */
+#define	EM_RISCV	243	/* RISC-V */
+
+/* Non-standard or deprecated. */
+#define	EM_486		6	/* Intel i486. */
+#define	EM_MIPS_RS4_BE	10	/* MIPS R4000 Big-Endian */
+#define	EM_ALPHA_STD	41	/* Digital Alpha (standard value). */
+#define	EM_ALPHA	0x9026	/* Alpha (written in the absence of an ABI) */
+
+/* e_flags for EM_ARM */
+#define EF_ARM_ABI_UNKNOWN	0x00000000
+#define EF_ARM_ABI_V5		0x05000000	/* ABI version 5 */
+#define EF_ARM_ABIMASK		0xFF000000
+#define EF_ARM_BE8		0x00800000
+#define EF_ARM_ABI_FLOAT_HARD	0x00000400	/* ABI version 5 and later */
+#define EF_ARM_ABI_FLOAT_SOFT	0x00000200	/* ABI version 5 and later */
+
+/* Special section indexes. */
+#define	SHN_UNDEF	     0		/* Undefined, missing, irrelevant. */
+#define	SHN_LORESERVE	0xff00		/* First of reserved range. */
+#define	SHN_LOPROC	0xff00		/* First processor-specific. */
+#define	SHN_HIPROC	0xff1f		/* Last processor-specific. */
+#define	SHN_LOOS	0xff20		/* First operating system-specific. */
+#define	SHN_HIOS	0xff3f		/* Last operating system-specific. */
+#define	SHN_ABS		0xfff1		/* Absolute values. */
+#define	SHN_COMMON	0xfff2		/* Common data. */
+#define	SHN_XINDEX	0xffff		/* Escape -- index stored elsewhere. */
+#define	SHN_HIRESERVE	0xffff		/* Last of reserved range. */
+
+/* sh_type */
+#define	SHT_NULL		0	/* inactive */
+#define	SHT_PROGBITS		1	/* program defined information */
+#define	SHT_SYMTAB		2	/* symbol table section */
+#define	SHT_STRTAB		3	/* string table section */
+#define	SHT_RELA		4	/* relocation section with addends */
+#define	SHT_HASH		5	/* symbol hash table section */
+#define	SHT_DYNAMIC		6	/* dynamic section */
+#define	SHT_NOTE		7	/* note section */
+#define	SHT_NOBITS		8	/* no space section */
+#define	SHT_REL			9	/* relocation section - no addends */
+#define	SHT_SHLIB		10	/* reserved - purpose unknown */
+#define	SHT_DYNSYM		11	/* dynamic symbol table section */
+#define	SHT_INIT_ARRAY		14	/* Initialization function pointers. */
+#define	SHT_FINI_ARRAY		15	/* Termination function pointers. */
+#define	SHT_PREINIT_ARRAY	16	/* Pre-initialization function ptrs. */
+#define	SHT_GROUP		17	/* Section group. */
+#define	SHT_SYMTAB_SHNDX	18	/* Section indexes (see SHN_XINDEX). */
+#define	SHT_LOOS		0x60000000	/* First of OS specific semantics */
+#define	SHT_LOSUNW		0x6ffffff4
+#define	SHT_SUNW_dof		0x6ffffff4
+#define	SHT_SUNW_cap		0x6ffffff5
+#define	SHT_SUNW_SIGNATURE	0x6ffffff6
+#define	SHT_GNU_HASH		0x6ffffff6
+#define	SHT_GNU_LIBLIST		0x6ffffff7
+#define	SHT_SUNW_ANNOTATE	0x6ffffff7
+#define	SHT_SUNW_DEBUGSTR	0x6ffffff8
+#define	SHT_SUNW_DEBUG		0x6ffffff9
+#define	SHT_SUNW_move		0x6ffffffa
+#define	SHT_SUNW_COMDAT		0x6ffffffb
+#define	SHT_SUNW_syminfo	0x6ffffffc
+#define	SHT_SUNW_verdef		0x6ffffffd
+#define	SHT_GNU_verdef		0x6ffffffd	/* Symbol versions provided */
+#define	SHT_SUNW_verneed	0x6ffffffe
+#define	SHT_GNU_verneed		0x6ffffffe	/* Symbol versions required */
+#define	SHT_SUNW_versym		0x6fffffff
+#define	SHT_GNU_versym		0x6fffffff	/* Symbol version table */
+#define	SHT_HISUNW		0x6fffffff
+#define	SHT_HIOS		0x6fffffff	/* Last of OS specific semantics */
+#define	SHT_LOPROC		0x70000000	/* reserved range for processor */
+#define	SHT_AMD64_UNWIND	0x70000001	/* unwind information */
+#define	SHT_ARM_EXIDX		0x70000001	/* Exception index table. */
+#define	SHT_ARM_PREEMPTMAP	0x70000002	/* BPABI DLL dynamic linking
+						   pre-emption map. */
+#define	SHT_ARM_ATTRIBUTES	0x70000003	/* Object file compatibility
+						   attributes. */
+#define	SHT_ARM_DEBUGOVERLAY	0x70000004	/* See DBGOVL for details. */
+#define	SHT_ARM_OVERLAYSECTION	0x70000005	/* See DBGOVL for details. */
+#define	SHT_MIPS_REGINFO	0x70000006
+#define	SHT_MIPS_OPTIONS	0x7000000d
+#define	SHT_MIPS_DWARF		0x7000001e	/* MIPS gcc uses MIPS_DWARF */
+#define	SHT_HIPROC		0x7fffffff	/* specific section header types */
+#define	SHT_LOUSER		0x80000000	/* reserved range for application */
+#define	SHT_HIUSER		0xffffffff	/* specific indexes */
+
+/* Flags for sh_flags. */
+#define	SHF_WRITE		0x1	/* Section contains writable data. */
+#define	SHF_ALLOC		0x2	/* Section occupies memory. */
+#define	SHF_EXECINSTR		0x4	/* Section contains instructions. */
+#define	SHF_MERGE		0x10	/* Section may be merged. */
+#define	SHF_STRINGS		0x20	/* Section contains strings. */
+#define	SHF_INFO_LINK		0x40	/* sh_info holds section index. */
+#define	SHF_LINK_ORDER		0x80	/* Special ordering requirements. */
+#define	SHF_OS_NONCONFORMING	0x100	/* OS-specific processing required. */
+#define	SHF_GROUP		0x200	/* Member of section group. */
+#define	SHF_TLS			0x400	/* Section contains TLS data. */
+#define	SHF_MASKOS	0x0ff00000	/* OS-specific semantics. */
+#define	SHF_MASKPROC	0xf0000000	/* Processor-specific semantics. */
+
+/* Values for p_type. */
+#define	PT_NULL		0	/* Unused entry. */
+#define	PT_LOAD		1	/* Loadable segment. */
+#define	PT_DYNAMIC	2	/* Dynamic linking information segment. */
+#define	PT_INTERP	3	/* Pathname of interpreter. */
+#define	PT_NOTE		4	/* Auxiliary information. */
+#define	PT_SHLIB	5	/* Reserved (not used). */
+#define	PT_PHDR		6	/* Location of program header itself. */
+#define	PT_TLS		7	/* Thread local storage segment */
+#define	PT_LOOS		0x60000000	/* First OS-specific. */
+#define	PT_SUNW_UNWIND	0x6464e550	/* amd64 UNWIND program header */
+#define	PT_GNU_EH_FRAME	0x6474e550
+#define	PT_GNU_STACK	0x6474e551
+#define	PT_GNU_RELRO	0x6474e552
+#define	PT_GNU_PROPERTY	0x6474e553
+#define	PT_LOSUNW	0x6ffffffa
+#define	PT_SUNWBSS	0x6ffffffa	/* Sun Specific segment */
+#define	PT_SUNWSTACK	0x6ffffffb	/* describes the stack segment */
+#define	PT_SUNWDTRACE	0x6ffffffc	/* private */
+#define	PT_SUNWCAP	0x6ffffffd	/* hard/soft capabilities segment */
+#define	PT_HISUNW	0x6fffffff
+#define	PT_HIOS		0x6fffffff	/* Last OS-specific. */
+#define	PT_LOPROC	0x70000000	/* First processor-specific type. */
+#define PT_ARM_EXIDX	0x70000001	/* .ARM.exidx segment */
+#define	PT_HIPROC	0x7fffffff	/* Last processor-specific type. */
+
+/* Values for p_flags. */
+#define	PF_X		0x1		/* Executable. */
+#define	PF_W		0x2		/* Writable. */
+#define	PF_R		0x4		/* Readable. */
+#define	PF_MASKOS	0x0ff00000	/* Operating system-specific. */
+#define	PF_MASKPROC	0xf0000000	/* Processor-specific. */
+
+/* Extended program header index. */
+#define	PN_XNUM		0xffff
+
+/* Values for d_tag. */
+#define	DT_NULL		0	/* Terminating entry. */
+#define	DT_NEEDED	1	/* String table offset of a needed shared
+				   library. */
+#define	DT_PLTRELSZ	2	/* Total size in bytes of PLT relocations. */
+#define	DT_PLTGOT	3	/* Processor-dependent address. */
+#define	DT_HASH		4	/* Address of symbol hash table. */
+#define	DT_STRTAB	5	/* Address of string table. */
+#define	DT_SYMTAB	6	/* Address of symbol table. */
+#define	DT_RELA		7	/* Address of ElfNN_Rela relocations. */
+#define	DT_RELASZ	8	/* Total size of ElfNN_Rela relocations. */
+#define	DT_RELAENT	9	/* Size of each ElfNN_Rela relocation entry. */
+#define	DT_STRSZ	10	/* Size of string table. */
+#define	DT_SYMENT	11	/* Size of each symbol table entry. */
+#define	DT_INIT		12	/* Address of initialization function. */
+#define	DT_FINI		13	/* Address of finalization function. */
+#define	DT_SONAME	14	/* String table offset of shared object
+				   name. */
+#define	DT_RPATH	15	/* String table offset of library path. [sup] */
+#define	DT_SYMBOLIC	16	/* Indicates "symbolic" linking. [sup] */
+#define	DT_REL		17	/* Address of ElfNN_Rel relocations. */
+#define	DT_RELSZ	18	/* Total size of ElfNN_Rel relocations. */
+#define	DT_RELENT	19	/* Size of each ElfNN_Rel relocation. */
+#define	DT_PLTREL	20	/* Type of relocation used for PLT. */
+#define	DT_DEBUG	21	/* Reserved (not used). */
+#define	DT_TEXTREL	22	/* Indicates there may be relocations in
+				   non-writable segments. [sup] */
+#define	DT_JMPREL	23	/* Address of PLT relocations. */
+#define	DT_BIND_NOW	24	/* [sup] */
+#define	DT_INIT_ARRAY	25	/* Address of the array of pointers to
+				   initialization functions */
+#define	DT_FINI_ARRAY	26	/* Address of the array of pointers to
+				   termination functions */
+#define	DT_INIT_ARRAYSZ	27	/* Size in bytes of the array of
+				   initialization functions. */
+#define	DT_FINI_ARRAYSZ	28	/* Size in bytes of the array of
+				   termination functions. */
+#define	DT_RUNPATH	29	/* String table offset of a null-terminated
+				   library search path string. */
+#define	DT_FLAGS	30	/* Object specific flag values. */
+#define	DT_ENCODING	32	/* Values greater than or equal to DT_ENCODING
+				   and less than DT_LOOS follow the rules for
+				   the interpretation of the d_un union
+				   as follows: even == 'd_ptr', odd == 'd_val'
+				   or none */
+#define	DT_PREINIT_ARRAY 32	/* Address of the array of pointers to
+				   pre-initialization functions. */
+#define	DT_PREINIT_ARRAYSZ 33	/* Size in bytes of the array of
+				   pre-initialization functions. */
+#define	DT_MAXPOSTAGS	34	/* number of positive tags */
+#define	DT_LOOS		0x6000000d	/* First OS-specific */
+#define	DT_SUNW_AUXILIARY	0x6000000d	/* symbol auxiliary name */
+#define	DT_SUNW_RTLDINF		0x6000000e	/* ld.so.1 info (private) */
+#define	DT_SUNW_FILTER		0x6000000f	/* symbol filter name */
+#define	DT_SUNW_CAP		0x60000010	/* hardware/software */
+#define	DT_HIOS		0x6ffff000	/* Last OS-specific */
+
+/*
+ * DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+ * Dyn.d_un.d_val field of the Elf*_Dyn structure.
+ */
+#define	DT_VALRNGLO	0x6ffffd00
+#define	DT_CHECKSUM	0x6ffffdf8	/* elf checksum */
+#define	DT_PLTPADSZ	0x6ffffdf9	/* pltpadding size */
+#define	DT_MOVEENT	0x6ffffdfa	/* move table entry size */
+#define	DT_MOVESZ	0x6ffffdfb	/* move table size */
+#define	DT_FEATURE_1	0x6ffffdfc	/* feature holder */
+#define	DT_POSFLAG_1	0x6ffffdfd	/* flags for DT_* entries, effecting */
+					/*	the following DT_* entry. */
+					/*	See DF_P1_* definitions */
+#define	DT_SYMINSZ	0x6ffffdfe	/* syminfo table size (in bytes) */
+#define	DT_SYMINENT	0x6ffffdff	/* syminfo entry size (in bytes) */
+#define	DT_VALRNGHI	0x6ffffdff
+
+/*
+ * DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+ * Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+ *
+ * If any adjustment is made to the ELF object after it has been
+ * built, these entries will need to be adjusted.
+ */
+#define	DT_ADDRRNGLO	0x6ffffe00
+#define	DT_GNU_HASH	0x6ffffef5	/* GNU-style hash table */
+#define	DT_CONFIG	0x6ffffefa	/* configuration information */
+#define	DT_DEPAUDIT	0x6ffffefb	/* dependency auditing */
+#define	DT_AUDIT	0x6ffffefc	/* object auditing */
+#define	DT_PLTPAD	0x6ffffefd	/* pltpadding (sparcv9) */
+#define	DT_MOVETAB	0x6ffffefe	/* move table */
+#define	DT_SYMINFO	0x6ffffeff	/* syminfo table */
+#define	DT_ADDRRNGHI	0x6ffffeff
+
+#define	DT_VERSYM	0x6ffffff0	/* Address of versym section. */
+#define	DT_RELACOUNT	0x6ffffff9	/* number of RELATIVE relocations */
+#define	DT_RELCOUNT	0x6ffffffa	/* number of RELATIVE relocations */
+#define	DT_FLAGS_1	0x6ffffffb	/* state flags - see DF_1_* defs */
+#define	DT_VERDEF	0x6ffffffc	/* Address of verdef section. */
+#define	DT_VERDEFNUM	0x6ffffffd	/* Number of elems in verdef section */
+#define	DT_VERNEED	0x6ffffffe	/* Address of verneed section. */
+#define	DT_VERNEEDNUM	0x6fffffff	/* Number of elems in verneed section */
+
+#define	DT_LOPROC	0x70000000	/* First processor-specific type. */
+#define	DT_DEPRECATED_SPARC_REGISTER	0x7000001
+#define	DT_AUXILIARY	0x7ffffffd	/* shared library auxiliary name */
+#define	DT_USED		0x7ffffffe	/* ignored - same as needed */
+#define	DT_FILTER	0x7fffffff	/* shared library filter name */
+#define	DT_HIPROC	0x7fffffff	/* Last processor-specific type. */
+
+/* Values for DT_FLAGS */
+#define	DF_ORIGIN	0x0001	/* Indicates that the object being loaded may
+				   make reference to the $ORIGIN substitution
+				   string */
+#define	DF_SYMBOLIC	0x0002	/* Indicates "symbolic" linking. */
+#define	DF_TEXTREL	0x0004	/* Indicates there may be relocations in
+				   non-writable segments. */
+#define	DF_BIND_NOW	0x0008	/* Indicates that the dynamic linker should
+				   process all relocations for the object
+				   containing this entry before transferring
+				   control to the program. */
+#define	DF_STATIC_TLS	0x0010	/* Indicates that the shared object or
+				   executable contains code using a static
+				   thread-local storage scheme. */
+
+/* Values for DT_FLAGS_1 */
+#define	DF_1_BIND_NOW	0x00000001	/* Same as DF_BIND_NOW */
+#define	DF_1_GLOBAL	0x00000002	/* Set the RTLD_GLOBAL for object */
+#define	DF_1_NODELETE	0x00000008	/* Set the RTLD_NODELETE for object */
+#define	DF_1_LOADFLTR	0x00000010	/* Immediate loading of filtees */
+#define	DF_1_NOOPEN     0x00000040	/* Do not allow loading on dlopen() */
+#define	DF_1_ORIGIN	0x00000080	/* Process $ORIGIN */
+#define	DF_1_INTERPOSE	0x00000400	/* Interpose all objects but main */
+#define	DF_1_NODEFLIB	0x00000800	/* Do not search default paths */
+
+/* Note section names */
+#define	ELF_NOTE_FREEBSD	"FreeBSD"
+#define	ELF_NOTE_NETBSD		"NetBSD"
+#define	ELF_NOTE_SOLARIS	"SUNW Solaris"
+#define	ELF_NOTE_GNU		"GNU"
+
+/* Values for n_type.  Used in core files. */
+#define	NT_PRSTATUS	1	/* Process status. */
+#define	NT_FPREGSET	2	/* Floating point registers. */
+#define	NT_PRPSINFO	3	/* Process state info. */
+#define	NT_THRMISC	7	/* Thread miscellaneous info. */
+#define	NT_PROCSTAT_PROC	8	/* Procstat proc data. */
+#define	NT_PROCSTAT_FILES	9	/* Procstat files data. */
+#define	NT_PROCSTAT_VMMAP	10	/* Procstat vmmap data. */
+#define	NT_PROCSTAT_GROUPS	11	/* Procstat groups data. */
+#define	NT_PROCSTAT_UMASK	12	/* Procstat umask data. */
+#define	NT_PROCSTAT_RLIMIT	13	/* Procstat rlimit data. */
+#define	NT_PROCSTAT_OSREL	14	/* Procstat osreldate data. */
+#define	NT_PROCSTAT_PSSTRINGS	15	/* Procstat ps_strings data. */
+#define	NT_PROCSTAT_AUXV	16	/* Procstat auxv data. */
+
+/* GNU note types. */
+#define	NT_GNU_ABI_TAG		1
+#define	NT_GNU_HWCAP		2
+#define	NT_GNU_BUILD_ID		3
+#define	NT_GNU_GOLD_VERSION	4
+#define	NT_GNU_PROPERTY_TYPE_0	5
+
+#define	GNU_PROPERTY_LOPROC			0xc0000000
+#define	GNU_PROPERTY_HIPROC			0xdfffffff
+
+#define	GNU_PROPERTY_AARCH64_FEATURE_1_AND	0xc0000000
+
+#define	GNU_PROPERTY_AARCH64_FEATURE_1_BTI	0x00000001
+#define	GNU_PROPERTY_AARCH64_FEATURE_1_PAC	0x00000002
+
+#define	GNU_PROPERTY_X86_FEATURE_1_AND		0xc0000002
+
+/* Symbol Binding - ELFNN_ST_BIND - st_info */
+#define	STB_LOCAL	0	/* Local symbol */
+#define	STB_GLOBAL	1	/* Global symbol */
+#define	STB_WEAK	2	/* like global - lower precedence */
+#define	STB_LOOS	10	/* Reserved range for operating system */
+#define	STB_HIOS	12	/*   specific semantics. */
+#define	STB_LOPROC	13	/* reserved range for processor */
+#define	STB_HIPROC	15	/*   specific semantics. */
+
+/* Symbol type - ELFNN_ST_TYPE - st_info */
+#define	STT_NOTYPE	0	/* Unspecified type. */
+#define	STT_OBJECT	1	/* Data object. */
+#define	STT_FUNC	2	/* Function. */
+#define	STT_SECTION	3	/* Section. */
+#define	STT_FILE	4	/* Source file. */
+#define	STT_COMMON	5	/* Uninitialized common block. */
+#define	STT_TLS		6	/* TLS object. */
+#define	STT_NUM		7
+#define	STT_LOOS	10	/* Reserved range for operating system */
+#define	STT_GNU_IFUNC	10
+#define	STT_HIOS	12	/*   specific semantics. */
+#define	STT_LOPROC	13	/* reserved range for processor */
+#define	STT_HIPROC	15	/*   specific semantics. */
+
+/* Symbol visibility - ELFNN_ST_VISIBILITY - st_other */
+#define	STV_DEFAULT	0x0	/* Default visibility (see binding). */
+#define	STV_INTERNAL	0x1	/* Special meaning in relocatable objects. */
+#define	STV_HIDDEN	0x2	/* Not visible. */
+#define	STV_PROTECTED	0x3	/* Visible but not preemptible. */
+#define	STV_EXPORTED	0x4
+#define	STV_SINGLETON	0x5
+#define	STV_ELIMINATE	0x6
+
+/* Special symbol table indexes. */
+#define	STN_UNDEF	0	/* Undefined symbol index. */
+
+/* Symbol versioning flags. */
+#define	VER_DEF_CURRENT	1
+#define	VER_DEF_IDX(x)	VER_NDX(x)
+
+#define	VER_FLG_BASE	0x01
+#define	VER_FLG_WEAK	0x02
+
+#define	VER_NEED_CURRENT	1
+#define	VER_NEED_WEAK	(1u << 15)
+#define	VER_NEED_HIDDEN	VER_NDX_HIDDEN
+#define	VER_NEED_IDX(x)	VER_NDX(x)
+
+#define	VER_NDX_LOCAL	0
+#define	VER_NDX_GLOBAL	1
+#define	VER_NDX_GIVEN	2
+
+#define	VER_NDX_HIDDEN	(1u << 15)
+#define	VER_NDX(x)	((x) & ~(1u << 15))
+
+#define	CA_SUNW_NULL	0
+#define	CA_SUNW_HW_1	1		/* first hardware capabilities entry */
+#define	CA_SUNW_SF_1	2		/* first software capabilities entry */
+
+/*
+ * Syminfo flag values
+ */
+#define	SYMINFO_FLG_DIRECT	0x0001	/* symbol ref has direct association */
+					/*	to object containing defn. */
+#define	SYMINFO_FLG_PASSTHRU	0x0002	/* ignored - see SYMINFO_FLG_FILTER */
+#define	SYMINFO_FLG_COPY	0x0004	/* symbol is a copy-reloc */
+#define	SYMINFO_FLG_LAZYLOAD	0x0008	/* object containing defn should be */
+					/*	lazily-loaded */
+#define	SYMINFO_FLG_DIRECTBIND	0x0010	/* ref should be bound directly to */
+					/*	object containing defn. */
+#define	SYMINFO_FLG_NOEXTDIRECT	0x0020	/* don't let an external reference */
+					/*	directly bind to this symbol */
+#define	SYMINFO_FLG_FILTER	0x0002	/* symbol ref is associated to a */
+#define	SYMINFO_FLG_AUXILIARY	0x0040	/* 	standard or auxiliary filter */
+
+/*
+ * Syminfo.si_boundto values.
+ */
+#define	SYMINFO_BT_SELF		0xffff	/* symbol bound to self */
+#define	SYMINFO_BT_PARENT	0xfffe	/* symbol bound to parent */
+#define	SYMINFO_BT_NONE		0xfffd	/* no special symbol binding */
+#define	SYMINFO_BT_EXTERN	0xfffc	/* symbol defined as external */
+#define	SYMINFO_BT_LOWRESERVE	0xff00	/* beginning of reserved entries */
+
+/*
+ * Syminfo version values.
+ */
+#define	SYMINFO_NONE		0	/* Syminfo version */
+#define	SYMINFO_CURRENT		1
+#define	SYMINFO_NUM		2
+
+/*
+ * Relocation types.
+ *
+ * All machine architectures are defined here to allow tools on one to
+ * handle others.
+ */
+
+#define	R_386_NONE		0	/* No relocation. */
+#define	R_386_32		1	/* Add symbol value. */
+#define	R_386_PC32		2	/* Add PC-relative symbol value. */
+#define	R_386_GOT32		3	/* Add PC-relative GOT offset. */
+#define	R_386_PLT32		4	/* Add PC-relative PLT offset. */
+#define	R_386_COPY		5	/* Copy data from shared object. */
+#define	R_386_GLOB_DAT		6	/* Set GOT entry to data address. */
+#define	R_386_JMP_SLOT		7	/* Set GOT entry to code address. */
+#define	R_386_RELATIVE		8	/* Add load address of shared object. */
+#define	R_386_GOTOFF		9	/* Add GOT-relative symbol address. */
+#define	R_386_GOTPC		10	/* Add PC-relative GOT table address. */
+#define	R_386_TLS_TPOFF		14	/* Negative offset in static TLS block */
+#define	R_386_TLS_IE		15	/* Absolute address of GOT for -ve static TLS */
+#define	R_386_TLS_GOTIE		16	/* GOT entry for negative static TLS block */
+#define	R_386_TLS_LE		17	/* Negative offset relative to static TLS */
+#define	R_386_TLS_GD		18	/* 32 bit offset to GOT (index,off) pair */
+#define	R_386_TLS_LDM		19	/* 32 bit offset to GOT (index,zero) pair */
+#define	R_386_TLS_GD_32		24	/* 32 bit offset to GOT (index,off) pair */
+#define	R_386_TLS_GD_PUSH	25	/* pushl instruction for Sun ABI GD sequence */
+#define	R_386_TLS_GD_CALL	26	/* call instruction for Sun ABI GD sequence */
+#define	R_386_TLS_GD_POP	27	/* popl instruction for Sun ABI GD sequence */
+#define	R_386_TLS_LDM_32	28	/* 32 bit offset to GOT (index,zero) pair */
+#define	R_386_TLS_LDM_PUSH	29	/* pushl instruction for Sun ABI LD sequence */
+#define	R_386_TLS_LDM_CALL	30	/* call instruction for Sun ABI LD sequence */
+#define	R_386_TLS_LDM_POP	31	/* popl instruction for Sun ABI LD sequence */
+#define	R_386_TLS_LDO_32	32	/* 32 bit offset from start of TLS block */
+#define	R_386_TLS_IE_32		33	/* 32 bit offset to GOT static TLS offset entry */
+#define	R_386_TLS_LE_32		34	/* 32 bit offset within static TLS block */
+#define	R_386_TLS_DTPMOD32	35	/* GOT entry containing TLS index */
+#define	R_386_TLS_DTPOFF32	36	/* GOT entry containing TLS offset */
+#define	R_386_TLS_TPOFF32	37	/* GOT entry of -ve static TLS offset */
+#define	R_386_IRELATIVE		42	/* PLT entry resolved indirectly at runtime */
+
+#define	R_RISCV_NONE		0	/* No relocation. */
+#define	R_RISCV_64		2	/* 64-bit relocation. */
+#define	R_RISCV_RELATIVE	3	/* Adjust a link address (A) to its
+					   load address (B + A). */
+#define	R_RISCV_JUMP_SLOT	5	/* Indicates the symbol associated
+					   with a PLT entry. */
+
+#define	R_AARCH64_NONE		0	/* No relocation. */
+#define	R_AARCH64_ABS64		257
+#define	R_AARCH64_GLOB_DAT	1025	/* Set GOT entry to data address. */
+#define	R_AARCH64_JUMP_SLOT	1026	/* Set GOT entry to code address. */
+#define	R_AARCH64_RELATIVE	1027	/* Add load address of shared object. */
+#define	R_AARCH64_TLS_TPREL	1030	/* Offset of the TLS block in the TCB */
+#define	R_AARCH64_TLSDESC	1031	/* TLS descriptor to be filled */
+
+#define	R_ARM_NONE		0	/* No relocation. */
+#define	R_ARM_PC24		1
+#define	R_ARM_ABS32		2
+#define	R_ARM_REL32		3
+#define	R_ARM_PC13		4
+#define	R_ARM_ABS16		5
+#define	R_ARM_ABS12		6
+#define	R_ARM_THM_ABS5		7
+#define	R_ARM_ABS8		8
+#define	R_ARM_SBREL32		9
+#define	R_ARM_THM_PC22		10
+#define	R_ARM_THM_PC8		11
+#define	R_ARM_AMP_VCALL9	12
+#define	R_ARM_SWI24		13
+#define	R_ARM_THM_SWI8		14
+#define	R_ARM_XPC25		15
+#define	R_ARM_THM_XPC22		16
+/* TLS relocations */
+#define	R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
+#define	R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
+#define	R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
+#define	R_ARM_COPY		20	/* Copy data from shared object. */
+#define	R_ARM_GLOB_DAT		21	/* Set GOT entry to data address. */
+#define	R_ARM_JUMP_SLOT		22	/* Set GOT entry to code address. */
+#define	R_ARM_RELATIVE		23	/* Add load address of shared object. */
+#define	R_ARM_GOTOFF		24	/* Add GOT-relative symbol address. */
+#define	R_ARM_GOTPC		25	/* Add PC-relative GOT table address. */
+#define	R_ARM_GOT32		26	/* Add PC-relative GOT offset. */
+#define	R_ARM_PLT32		27	/* Add PC-relative PLT offset. */
+#define	R_ARM_GNU_VTENTRY	100
+#define	R_ARM_GNU_VTINHERIT	101
+#define	R_ARM_RSBREL32		250
+#define	R_ARM_THM_RPC22		251
+#define	R_ARM_RREL32		252
+#define	R_ARM_RABS32		253
+#define	R_ARM_RPC24		254
+#define	R_ARM_RBASE		255
+
+/*	Name			Value	   Field	Calculation */
+#define	R_IA_64_NONE		0	/* None */
+#define	R_IA_64_IMM14		0x21	/* immediate14	S + A */
+#define	R_IA_64_IMM22		0x22	/* immediate22	S + A */
+#define	R_IA_64_IMM64		0x23	/* immediate64	S + A */
+#define	R_IA_64_DIR32MSB	0x24	/* word32 MSB	S + A */
+#define	R_IA_64_DIR32LSB	0x25	/* word32 LSB	S + A */
+#define	R_IA_64_DIR64MSB	0x26	/* word64 MSB	S + A */
+#define	R_IA_64_DIR64LSB	0x27	/* word64 LSB	S + A */
+#define	R_IA_64_GPREL22		0x2a	/* immediate22	@gprel(S + A) */
+#define	R_IA_64_GPREL64I	0x2b	/* immediate64	@gprel(S + A) */
+#define	R_IA_64_GPREL32MSB	0x2c	/* word32 MSB	@gprel(S + A) */
+#define	R_IA_64_GPREL32LSB	0x2d	/* word32 LSB	@gprel(S + A) */
+#define	R_IA_64_GPREL64MSB	0x2e	/* word64 MSB	@gprel(S + A) */
+#define	R_IA_64_GPREL64LSB	0x2f	/* word64 LSB	@gprel(S + A) */
+#define	R_IA_64_LTOFF22		0x32	/* immediate22	@ltoff(S + A) */
+#define	R_IA_64_LTOFF64I	0x33	/* immediate64	@ltoff(S + A) */
+#define	R_IA_64_PLTOFF22	0x3a	/* immediate22	@pltoff(S + A) */
+#define	R_IA_64_PLTOFF64I	0x3b	/* immediate64	@pltoff(S + A) */
+#define	R_IA_64_PLTOFF64MSB	0x3e	/* word64 MSB	@pltoff(S + A) */
+#define	R_IA_64_PLTOFF64LSB	0x3f	/* word64 LSB	@pltoff(S + A) */
+#define	R_IA_64_FPTR64I		0x43	/* immediate64	@fptr(S + A) */
+#define	R_IA_64_FPTR32MSB	0x44	/* word32 MSB	@fptr(S + A) */
+#define	R_IA_64_FPTR32LSB	0x45	/* word32 LSB	@fptr(S + A) */
+#define	R_IA_64_FPTR64MSB	0x46	/* word64 MSB	@fptr(S + A) */
+#define	R_IA_64_FPTR64LSB	0x47	/* word64 LSB	@fptr(S + A) */
+#define	R_IA_64_PCREL60B	0x48	/* immediate60 form1 S + A - P */
+#define	R_IA_64_PCREL21B	0x49	/* immediate21 form1 S + A - P */
+#define	R_IA_64_PCREL21M	0x4a	/* immediate21 form2 S + A - P */
+#define	R_IA_64_PCREL21F	0x4b	/* immediate21 form3 S + A - P */
+#define	R_IA_64_PCREL32MSB	0x4c	/* word32 MSB	S + A - P */
+#define	R_IA_64_PCREL32LSB	0x4d	/* word32 LSB	S + A - P */
+#define	R_IA_64_PCREL64MSB	0x4e	/* word64 MSB	S + A - P */
+#define	R_IA_64_PCREL64LSB	0x4f	/* word64 LSB	S + A - P */
+#define	R_IA_64_LTOFF_FPTR22	0x52	/* immediate22	@ltoff(@fptr(S + A)) */
+#define	R_IA_64_LTOFF_FPTR64I	0x53	/* immediate64	@ltoff(@fptr(S + A)) */
+#define	R_IA_64_LTOFF_FPTR32MSB	0x54	/* word32 MSB	@ltoff(@fptr(S + A)) */
+#define	R_IA_64_LTOFF_FPTR32LSB	0x55	/* word32 LSB	@ltoff(@fptr(S + A)) */
+#define	R_IA_64_LTOFF_FPTR64MSB	0x56	/* word64 MSB	@ltoff(@fptr(S + A)) */
+#define	R_IA_64_LTOFF_FPTR64LSB	0x57	/* word64 LSB	@ltoff(@fptr(S + A)) */
+#define	R_IA_64_SEGREL32MSB	0x5c	/* word32 MSB	@segrel(S + A) */
+#define	R_IA_64_SEGREL32LSB	0x5d	/* word32 LSB	@segrel(S + A) */
+#define	R_IA_64_SEGREL64MSB	0x5e	/* word64 MSB	@segrel(S + A) */
+#define	R_IA_64_SEGREL64LSB	0x5f	/* word64 LSB	@segrel(S + A) */
+#define	R_IA_64_SECREL32MSB	0x64	/* word32 MSB	@secrel(S + A) */
+#define	R_IA_64_SECREL32LSB	0x65	/* word32 LSB	@secrel(S + A) */
+#define	R_IA_64_SECREL64MSB	0x66	/* word64 MSB	@secrel(S + A) */
+#define	R_IA_64_SECREL64LSB	0x67	/* word64 LSB	@secrel(S + A) */
+#define	R_IA_64_REL32MSB	0x6c	/* word32 MSB	BD + A */
+#define	R_IA_64_REL32LSB	0x6d	/* word32 LSB	BD + A */
+#define	R_IA_64_REL64MSB	0x6e	/* word64 MSB	BD + A */
+#define	R_IA_64_REL64LSB	0x6f	/* word64 LSB	BD + A */
+#define	R_IA_64_LTV32MSB	0x74	/* word32 MSB	S + A */
+#define	R_IA_64_LTV32LSB	0x75	/* word32 LSB	S + A */
+#define	R_IA_64_LTV64MSB	0x76	/* word64 MSB	S + A */
+#define	R_IA_64_LTV64LSB	0x77	/* word64 LSB	S + A */
+#define	R_IA_64_PCREL21BI	0x79	/* immediate21 form1 S + A - P */
+#define	R_IA_64_PCREL22		0x7a	/* immediate22	S + A - P */
+#define	R_IA_64_PCREL64I	0x7b	/* immediate64	S + A - P */
+#define	R_IA_64_IPLTMSB		0x80	/* function descriptor MSB special */
+#define	R_IA_64_IPLTLSB		0x81	/* function descriptor LSB speciaal */
+#define	R_IA_64_SUB		0x85	/* immediate64	A - S */
+#define	R_IA_64_LTOFF22X	0x86	/* immediate22	special */
+#define	R_IA_64_LDXMOV		0x87	/* immediate22	special */
+#define	R_IA_64_TPREL14		0x91	/* imm14	@tprel(S + A) */
+#define	R_IA_64_TPREL22		0x92	/* imm22	@tprel(S + A) */
+#define	R_IA_64_TPREL64I	0x93	/* imm64	@tprel(S + A) */
+#define	R_IA_64_TPREL64MSB	0x96	/* word64 MSB	@tprel(S + A) */
+#define	R_IA_64_TPREL64LSB	0x97	/* word64 LSB	@tprel(S + A) */
+#define	R_IA_64_LTOFF_TPREL22	0x9a	/* imm22	@ltoff(@tprel(S+A)) */
+#define	R_IA_64_DTPMOD64MSB	0xa6	/* word64 MSB	@dtpmod(S + A) */
+#define	R_IA_64_DTPMOD64LSB	0xa7	/* word64 LSB	@dtpmod(S + A) */
+#define	R_IA_64_LTOFF_DTPMOD22	0xaa	/* imm22	@ltoff(@dtpmod(S+A)) */
+#define	R_IA_64_DTPREL14	0xb1	/* imm14	@dtprel(S + A) */
+#define	R_IA_64_DTPREL22	0xb2	/* imm22	@dtprel(S + A) */
+#define	R_IA_64_DTPREL64I	0xb3	/* imm64	@dtprel(S + A) */
+#define	R_IA_64_DTPREL32MSB	0xb4	/* word32 MSB	@dtprel(S + A) */
+#define	R_IA_64_DTPREL32LSB	0xb5	/* word32 LSB	@dtprel(S + A) */
+#define	R_IA_64_DTPREL64MSB	0xb6	/* word64 MSB	@dtprel(S + A) */
+#define	R_IA_64_DTPREL64LSB	0xb7	/* word64 LSB	@dtprel(S + A) */
+#define	R_IA_64_LTOFF_DTPREL22	0xba	/* imm22	@ltoff(@dtprel(S+A)) */
+
+#define	R_MIPS_NONE	0	/* No reloc */
+#define	R_MIPS_16	1	/* Direct 16 bit */
+#define	R_MIPS_32	2	/* Direct 32 bit */
+#define	R_MIPS_REL32	3	/* PC relative 32 bit */
+#define	R_MIPS_26	4	/* Direct 26 bit shifted */
+#define	R_MIPS_HI16	5	/* High 16 bit */
+#define	R_MIPS_LO16	6	/* Low 16 bit */
+#define	R_MIPS_GPREL16	7	/* GP relative 16 bit */
+#define	R_MIPS_LITERAL	8	/* 16 bit literal entry */
+#define	R_MIPS_GOT16	9	/* 16 bit GOT entry */
+#define	R_MIPS_PC16	10	/* PC relative 16 bit */
+#define	R_MIPS_CALL16	11	/* 16 bit GOT entry for function */
+#define	R_MIPS_GPREL32	12	/* GP relative 32 bit */
+#define	R_MIPS_64	18	/* Direct 64 bit */
+#define	R_MIPS_GOTHI16	21	/* GOT HI 16 bit */
+#define	R_MIPS_GOTLO16	22	/* GOT LO 16 bit */
+#define	R_MIPS_CALLHI16 30	/* upper 16 bit GOT entry for function */
+#define	R_MIPS_CALLLO16 31	/* lower 16 bit GOT entry for function */
+
+#define	R_PPC_NONE		0	/* No relocation. */
+#define	R_PPC_ADDR32		1
+#define	R_PPC_ADDR24		2
+#define	R_PPC_ADDR16		3
+#define	R_PPC_ADDR16_LO		4
+#define	R_PPC_ADDR16_HI		5
+#define	R_PPC_ADDR16_HA		6
+#define	R_PPC_ADDR14		7
+#define	R_PPC_ADDR14_BRTAKEN	8
+#define	R_PPC_ADDR14_BRNTAKEN	9
+#define	R_PPC_REL24		10
+#define	R_PPC_REL14		11
+#define	R_PPC_REL14_BRTAKEN	12
+#define	R_PPC_REL14_BRNTAKEN	13
+#define	R_PPC_GOT16		14
+#define	R_PPC_GOT16_LO		15
+#define	R_PPC_GOT16_HI		16
+#define	R_PPC_GOT16_HA		17
+#define	R_PPC_PLTREL24		18
+#define	R_PPC_COPY		19
+#define	R_PPC_GLOB_DAT		20
+#define	R_PPC_JMP_SLOT		21
+#define	R_PPC_RELATIVE		22
+#define	R_PPC_LOCAL24PC		23
+#define	R_PPC_UADDR32		24
+#define	R_PPC_UADDR16		25
+#define	R_PPC_REL32		26
+#define	R_PPC_PLT32		27
+#define	R_PPC_PLTREL32		28
+#define	R_PPC_PLT16_LO		29
+#define	R_PPC_PLT16_HI		30
+#define	R_PPC_PLT16_HA		31
+#define	R_PPC_SDAREL16		32
+#define	R_PPC_SECTOFF		33
+#define	R_PPC_SECTOFF_LO	34
+#define	R_PPC_SECTOFF_HI	35
+#define	R_PPC_SECTOFF_HA	36
+
+/*
+ * 64-bit relocations
+ */
+#define	R_PPC64_ADDR64		38
+#define	R_PPC64_ADDR16_HIGHER	39
+#define	R_PPC64_ADDR16_HIGHERA	40
+#define	R_PPC64_ADDR16_HIGHEST	41
+#define	R_PPC64_ADDR16_HIGHESTA	42
+#define	R_PPC64_UADDR64		43
+#define	R_PPC64_REL64		44
+#define	R_PPC64_PLT64		45
+#define	R_PPC64_PLTREL64	46
+#define	R_PPC64_TOC16		47
+#define	R_PPC64_TOC16_LO	48
+#define	R_PPC64_TOC16_HI	49
+#define	R_PPC64_TOC16_HA	50
+#define	R_PPC64_TOC		51
+#define	R_PPC64_DTPMOD64	68
+#define	R_PPC64_TPREL64		73
+#define	R_PPC64_DTPREL64	78
+
+/*
+ * TLS relocations
+ */
+#define	R_PPC_TLS		67
+#define	R_PPC_DTPMOD32		68
+#define	R_PPC_TPREL16		69
+#define	R_PPC_TPREL16_LO	70
+#define	R_PPC_TPREL16_HI	71
+#define	R_PPC_TPREL16_HA	72
+#define	R_PPC_TPREL32		73
+#define	R_PPC_DTPREL16		74
+#define	R_PPC_DTPREL16_LO	75
+#define	R_PPC_DTPREL16_HI	76
+#define	R_PPC_DTPREL16_HA	77
+#define	R_PPC_DTPREL32		78
+#define	R_PPC_GOT_TLSGD16	79
+#define	R_PPC_GOT_TLSGD16_LO	80
+#define	R_PPC_GOT_TLSGD16_HI	81
+#define	R_PPC_GOT_TLSGD16_HA	82
+#define	R_PPC_GOT_TLSLD16	83
+#define	R_PPC_GOT_TLSLD16_LO	84
+#define	R_PPC_GOT_TLSLD16_HI	85
+#define	R_PPC_GOT_TLSLD16_HA	86
+#define	R_PPC_GOT_TPREL16	87
+#define	R_PPC_GOT_TPREL16_LO	88
+#define	R_PPC_GOT_TPREL16_HI	89
+#define	R_PPC_GOT_TPREL16_HA	90
+
+/*
+ * The remaining relocs are from the Embedded ELF ABI, and are not in the
+ *  SVR4 ELF ABI.
+ */
+
+#define	R_PPC_EMB_NADDR32	101
+#define	R_PPC_EMB_NADDR16	102
+#define	R_PPC_EMB_NADDR16_LO	103
+#define	R_PPC_EMB_NADDR16_HI	104
+#define	R_PPC_EMB_NADDR16_HA	105
+#define	R_PPC_EMB_SDAI16	106
+#define	R_PPC_EMB_SDA2I16	107
+#define	R_PPC_EMB_SDA2REL	108
+#define	R_PPC_EMB_SDA21		109
+#define	R_PPC_EMB_MRKREF	110
+#define	R_PPC_EMB_RELSEC16	111
+#define	R_PPC_EMB_RELST_LO	112
+#define	R_PPC_EMB_RELST_HI	113
+#define	R_PPC_EMB_RELST_HA	114
+#define	R_PPC_EMB_BIT_FLD	115
+#define	R_PPC_EMB_RELSDA	116
+
+#define	R_SPARC_NONE		0
+#define	R_SPARC_8		1
+#define	R_SPARC_16		2
+#define	R_SPARC_32		3
+#define	R_SPARC_DISP8		4
+#define	R_SPARC_DISP16		5
+#define	R_SPARC_DISP32		6
+#define	R_SPARC_WDISP30		7
+#define	R_SPARC_WDISP22		8
+#define	R_SPARC_HI22		9
+#define	R_SPARC_22		10
+#define	R_SPARC_13		11
+#define	R_SPARC_LO10		12
+#define	R_SPARC_GOT10		13
+#define	R_SPARC_GOT13		14
+#define	R_SPARC_GOT22		15
+#define	R_SPARC_PC10		16
+#define	R_SPARC_PC22		17
+#define	R_SPARC_WPLT30		18
+#define	R_SPARC_COPY		19
+#define	R_SPARC_GLOB_DAT	20
+#define	R_SPARC_JMP_SLOT	21
+#define	R_SPARC_RELATIVE	22
+#define	R_SPARC_UA32		23
+#define	R_SPARC_PLT32		24
+#define	R_SPARC_HIPLT22		25
+#define	R_SPARC_LOPLT10		26
+#define	R_SPARC_PCPLT32		27
+#define	R_SPARC_PCPLT22		28
+#define	R_SPARC_PCPLT10		29
+#define	R_SPARC_10		30
+#define	R_SPARC_11		31
+#define	R_SPARC_64		32
+#define	R_SPARC_OLO10		33
+#define	R_SPARC_HH22		34
+#define	R_SPARC_HM10		35
+#define	R_SPARC_LM22		36
+#define	R_SPARC_PC_HH22		37
+#define	R_SPARC_PC_HM10		38
+#define	R_SPARC_PC_LM22		39
+#define	R_SPARC_WDISP16		40
+#define	R_SPARC_WDISP19		41
+#define	R_SPARC_GLOB_JMP	42
+#define	R_SPARC_7		43
+#define	R_SPARC_5		44
+#define	R_SPARC_6		45
+#define	R_SPARC_DISP64		46
+#define	R_SPARC_PLT64		47
+#define	R_SPARC_HIX22		48
+#define	R_SPARC_LOX10		49
+#define	R_SPARC_H44		50
+#define	R_SPARC_M44		51
+#define	R_SPARC_L44		52
+#define	R_SPARC_REGISTER	53
+#define	R_SPARC_UA64		54
+#define	R_SPARC_UA16		55
+#define	R_SPARC_TLS_GD_HI22	56
+#define	R_SPARC_TLS_GD_LO10	57
+#define	R_SPARC_TLS_GD_ADD	58
+#define	R_SPARC_TLS_GD_CALL	59
+#define	R_SPARC_TLS_LDM_HI22	60
+#define	R_SPARC_TLS_LDM_LO10	61
+#define	R_SPARC_TLS_LDM_ADD	62
+#define	R_SPARC_TLS_LDM_CALL	63
+#define	R_SPARC_TLS_LDO_HIX22	64
+#define	R_SPARC_TLS_LDO_LOX10	65
+#define	R_SPARC_TLS_LDO_ADD	66
+#define	R_SPARC_TLS_IE_HI22	67
+#define	R_SPARC_TLS_IE_LO10	68
+#define	R_SPARC_TLS_IE_LD	69
+#define	R_SPARC_TLS_IE_LDX	70
+#define	R_SPARC_TLS_IE_ADD	71
+#define	R_SPARC_TLS_LE_HIX22	72
+#define	R_SPARC_TLS_LE_LOX10	73
+#define	R_SPARC_TLS_DTPMOD32	74
+#define	R_SPARC_TLS_DTPMOD64	75
+#define	R_SPARC_TLS_DTPOFF32	76
+#define	R_SPARC_TLS_DTPOFF64	77
+#define	R_SPARC_TLS_TPOFF32	78
+#define	R_SPARC_TLS_TPOFF64	79
+
+#define	R_X86_64_NONE		0	/* No relocation. */
+#define	R_X86_64_64		1	/* Add 64 bit symbol value. */
+#define	R_X86_64_PC32		2	/* PC-relative 32 bit signed sym value. */
+#define	R_X86_64_GOT32		3	/* PC-relative 32 bit GOT offset. */
+#define	R_X86_64_PLT32		4	/* PC-relative 32 bit PLT offset. */
+#define	R_X86_64_COPY		5	/* Copy data from shared object. */
+#define	R_X86_64_GLOB_DAT	6	/* Set GOT entry to data address. */
+#define	R_X86_64_JMP_SLOT	7	/* Set GOT entry to code address. */
+#define	R_X86_64_RELATIVE	8	/* Add load address of shared object. */
+#define	R_X86_64_GOTPCREL	9	/* Add 32 bit signed pcrel offset to GOT. */
+#define	R_X86_64_32		10	/* Add 32 bit zero extended symbol value */
+#define	R_X86_64_32S		11	/* Add 32 bit sign extended symbol value */
+#define	R_X86_64_16		12	/* Add 16 bit zero extended symbol value */
+#define	R_X86_64_PC16		13	/* Add 16 bit signed extended pc relative symbol value */
+#define	R_X86_64_8		14	/* Add 8 bit zero extended symbol value */
+#define	R_X86_64_PC8		15	/* Add 8 bit signed extended pc relative symbol value */
+#define	R_X86_64_DTPMOD64	16	/* ID of module containing symbol */
+#define	R_X86_64_DTPOFF64	17	/* Offset in TLS block */
+#define	R_X86_64_TPOFF64	18	/* Offset in static TLS block */
+#define	R_X86_64_TLSGD		19	/* PC relative offset to GD GOT entry */
+#define	R_X86_64_TLSLD		20	/* PC relative offset to LD GOT entry */
+#define	R_X86_64_DTPOFF32	21	/* Offset in TLS block */
+#define	R_X86_64_GOTTPOFF	22	/* PC relative offset to IE GOT entry */
+#define	R_X86_64_TPOFF32	23	/* Offset in static TLS block */
+#define	R_X86_64_IRELATIVE	37
+
+
+#endif /* !_SYS_ELF_COMMON_H_ */
diff --git a/components/common/uuid/uuid.c b/components/common/uuid/uuid.c
index 16b6730..85ac216 100644
--- a/components/common/uuid/uuid.c
+++ b/components/common/uuid/uuid.c
@@ -8,6 +8,7 @@
 #include <assert.h>
 #include <string.h>
 #include <ctype.h>
+#include <compiler.h>
 
 static uint8_t hex_to_nibble(char hex)
 {
@@ -189,7 +190,7 @@
 void uuid_octets_from_canonical(struct uuid_octets *uuid_octets,
 	const char *canonical_form)
 {
-	size_t valid_chars = uuid_parse_to_octets(canonical_form,
+	__maybe_unused size_t valid_chars = uuid_parse_to_octets(canonical_form,
 		uuid_octets->octets, sizeof(uuid_octets->octets));
 
 	/* Input string is assumed to be valid. Should not be used if canonical
@@ -201,7 +202,7 @@
 void uuid_guid_octets_from_canonical(struct uuid_octets *uuid_octets,
 	const char *canonical_form)
 {
-	size_t valid_chars = uuid_parse_to_guid_octets(canonical_form,
+	__maybe_unused size_t valid_chars = uuid_parse_to_guid_octets(canonical_form,
 		uuid_octets->octets, sizeof(uuid_octets->octets));
 
 	assert(valid_chars == UUID_CANONICAL_FORM_LEN);
diff --git a/components/config/loader/sp/sp_config_loader.c b/components/config/loader/sp/sp_config_loader.c
index 5c7c552..bebb4b4 100644
--- a/components/config/loader/sp/sp_config_loader.c
+++ b/components/config/loader/sp/sp_config_loader.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  */
 
 #include <common/fdt/fdt_helpers.h>
@@ -34,10 +34,15 @@
 	/* Iterate over the device regions */
 	while ((uintptr_t)d < (value_pair->value + value_pair->size)) {
 
-		struct device_region device_region;
+		struct device_region device_region = { 0 };
+		size_t name_length = strlen(d->name) + 1;
 
-		strncpy(device_region.dev_class, d->name,
-			sizeof(device_region.dev_class));
+		if (name_length > sizeof(device_region.dev_class)) {
+			EMSG("name too long");
+			return false;
+		}
+
+		memcpy(device_region.dev_class, d->name, name_length);
 		device_region.dev_instance = 0;
 		device_region.base_addr = d->location;
 		device_region.io_region_size = d->size;
@@ -63,10 +68,15 @@
 	/* Iterate over the device regions */
 	while ((uintptr_t)d < (value_pair->value + value_pair->size)) {
 
-		struct memory_region memory_region;
+		struct memory_region memory_region = { 0 };
+		size_t name_length = strlen(d->name) + 1;
 
-		strncpy(memory_region.region_name, d->name,
-			sizeof(memory_region.region_name));
+		if (name_length > sizeof(memory_region.region_name)) {
+			EMSG("name too long");
+			return false;
+		}
+
+		memcpy(memory_region.region_name, d->name, name_length);
 		memory_region.base_addr = d->location;
 		memory_region.region_size = d->size;
 
@@ -138,6 +148,7 @@
 			uint64_t base_addr = 0;
 			uint32_t page_cnt = 0;
 			const char *subnode_name = fdt_get_name(fdt, subnode, NULL);
+			size_t name_length = 0;
 
 			if (!subnode_name) {
 				EMSG("subnode name is missing");
@@ -154,8 +165,13 @@
 				return false;
 			}
 
-			strncpy(memory_region.region_name, subnode_name,
-				sizeof(memory_region.region_name));
+			name_length = strlen(subnode_name) + 1;
+			if (name_length > sizeof(memory_region.region_name)) {
+				EMSG("name too long");
+				return false;
+			}
+
+			memcpy(memory_region.region_name, subnode_name, name_length);
 			memory_region.base_addr = (uintptr_t)base_addr;
 			memory_region.region_size = page_cnt * FFA_SP_MANIFEST_PAGE_SIZE;
 
@@ -176,6 +192,7 @@
 			uint64_t base_addr = 0;
 			uint32_t page_cnt = 0;
 			const char *subnode_name = fdt_get_name(fdt, subnode, NULL);
+			size_t name_length = 0;
 
 			if (!subnode_name) {
 				EMSG("subnode name is missing");
@@ -192,8 +209,13 @@
 				return false;
 			}
 
-			strncpy(device_region.dev_class, subnode_name,
-				sizeof(device_region.dev_class));
+			name_length = strlen(subnode_name) + 1;
+			if (name_length > sizeof(device_region.dev_class)) {
+				EMSG("name too long");
+				return false;
+			}
+
+			memcpy(device_region.dev_class, subnode_name, name_length);
 			device_region.base_addr = base_addr;
 			device_region.io_region_size = page_cnt * FFA_SP_MANIFEST_PAGE_SIZE;
 			device_region.dev_instance = 0;
diff --git a/components/config/ramstore/config_ramstore.c b/components/config/ramstore/config_ramstore.c
index af26a57..838b420 100644
--- a/components/config/ramstore/config_ramstore.c
+++ b/components/config/ramstore/config_ramstore.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -27,19 +27,23 @@
 	const char *name, unsigned int instance,
 	const void *data, size_t size)
 {
-	struct config_container *container = malloc(sizeof(struct config_container) + size);
+	struct config_container *container = NULL;
+	size_t name_length = strlen(name) + 1;
 
-	if (container) {
+	if (name_length > sizeof(container->name))
+		return NULL;
 
-		container->classifier = classifier;
-		strncpy(container->name, name, sizeof(container->name));
-		container->name[sizeof(container->name) - 1] = '\0';
-		container->instance = instance;
-		container->size = size;
-		container->next = NULL;
+	container = malloc(sizeof(struct config_container) + size);
+	if (!container)
+		return NULL;
 
-		memcpy((uint8_t*)container + sizeof(struct config_container), data, size);
-	}
+	container->classifier = classifier;
+	memcpy(container->name, name, name_length);
+	container->instance = instance;
+	container->size = size;
+	container->next = NULL;
+
+	memcpy((uint8_t *)container + sizeof(struct config_container), data, size);
 
 	return container;
 }
diff --git a/components/media/disk/disk_images/readme.rst b/components/media/disk/disk_images/readme.rst
index 0f2d2c0..efb1f86 100644
--- a/components/media/disk/disk_images/readme.rst
+++ b/components/media/disk/disk_images/readme.rst
@@ -65,7 +65,7 @@
     * - components/media/disk/disk_images/multi_location_fw.img
       - This UEFI disk image contains the set of partitions you'd expect to find in flash for a
         device where firmware is distributed across multiple locations. In this case, there are
-        locations for AP firmware, SCP firmware and RSS firmware.
+        locations for AP firmware, SCP firmware and RSE firmware.
 
 
 --------------
diff --git a/components/messaging/ffa/libsp/aarch64/ffa_syscalls_a64.S b/components/messaging/ffa/libsp/aarch64/ffa_syscalls_a64.S
index 6ffeb0b..d883ecb 100644
--- a/components/messaging/ffa/libsp/aarch64/ffa_syscalls_a64.S
+++ b/components/messaging/ffa/libsp/aarch64/ffa_syscalls_a64.S
@@ -25,3 +25,5 @@
 	stp	x6, x7, [x8, #48]
 	ret
 	END_FUNC ffa_svc
+
+BTI(emit_aarch64_feature_1_and     GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
diff --git a/components/messaging/ffa/libsp/component.cmake b/components/messaging/ffa/libsp/component.cmake
index 64e8814..8d72089 100644
--- a/components/messaging/ffa/libsp/component.cmake
+++ b/components/messaging/ffa/libsp/component.cmake
@@ -9,6 +9,7 @@
 endif()
 
 set(FFA_DIRECT_MSG_ROUTING_EXTENSION ON CACHE BOOL "Enable FF-A direct message routing extension")
+set(CFG_FFA_VERSION 0x00010001 CACHE STRING "The supported FF-A protocol's version: (major << 16) | minor")
 
 target_sources(${TGT} PRIVATE
 	"${CMAKE_CURRENT_LIST_DIR}/aarch64/ffa_syscalls_a64.S"
@@ -46,6 +47,11 @@
 		)
 endif()
 
+target_compile_definitions(${TGT}
+	PUBLIC
+		"CFG_FFA_VERSION=${CFG_FFA_VERSION}"
+	)
+
 target_include_directories(${TGT}
 	 PUBLIC
 		"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
diff --git a/components/messaging/ffa/libsp/ffa.c b/components/messaging/ffa/libsp/ffa.c
index 6a51379..76f0eda 100644
--- a/components/messaging/ffa/libsp/ffa.c
+++ b/components/messaging/ffa/libsp/ffa.c
@@ -79,7 +79,7 @@
 	uint32_t self_version = 0;
 
 	self_version = (FFA_VERSION_MAJOR << FFA_VERSION_MAJOR_SHIFT) |
-		       (FFA_VERSION_MINOR << FFA_VERSION_MINOR);
+		       (FFA_VERSION_MINOR << FFA_VERSION_MINOR_SHIFT);
 
 	ffa_svc(FFA_VERSION, self_version, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
 		FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
@@ -173,6 +173,7 @@
 	return FFA_OK;
 }
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t *count)
 {
 	struct ffa_params result = {0};
@@ -193,6 +194,31 @@
 	*count = result.a2;
 	return FFA_OK;
 }
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t flags, uint32_t *count,
+				  uint32_t *size)
+{
+	struct ffa_params result = {0};
+	uint32_t abi_uuid[4] = {0};
+
+	ffa_uuid_to_abi_format(uuid, abi_uuid);
+
+	ffa_svc(FFA_PARTITION_INFO_GET, abi_uuid[0], abi_uuid[1], abi_uuid[2],
+		abi_uuid[3], flags, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+		&result);
+
+	if (result.a0 == FFA_ERROR) {
+		*count = UINT32_C(0);
+		*size = UINT32_C(0);
+		return ffa_get_errorcode(&result);
+	}
+
+	assert(result.a0 == FFA_SUCCESS_32);
+	*count = result.a2;
+	*size = result.a3;
+	return FFA_OK;
+}
+#endif /* CFG_FFA_VERSION */
 
 ffa_result ffa_id_get(uint16_t *id)
 {
@@ -212,6 +238,41 @@
 	return FFA_OK;
 }
 
+static void handle_framework_msg(struct ffa_params *result)
+{
+	if (result->a0 == FFA_INTERRUPT) {
+		ffa_interrupt_handler(result->a2);
+		ffa_return_from_interrupt(result);
+	} else if (result->a0 == FFA_MSG_SEND_DIRECT_REQ_32 && FFA_IS_FRAMEWORK_MSG(result->a2)) {
+		ffa_result res = FFA_OK;
+		uint16_t src_id = result->a1 >> 16;
+		uint16_t dst_id = result->a1;
+		uint64_t handle = reg_pair_to_64(result->a4, result->a3);
+		uint16_t vm_id = result->a5;
+
+		switch (result->a2 & FFA_FRAMEWORK_MSG_TYPE_MASK) {
+		case FFA_FRAMEWORK_MSG_VM_CREATED:
+			res = ffa_vm_created_handler(vm_id, handle);
+			ffa_svc(FFA_MSG_SEND_DIRECT_RESP_32, ((uint32_t)dst_id << 16) | src_id,
+				FFA_MSG_FLAG_FRAMEWORK | FFA_FRAMEWORK_MSG_VM_CREATED_ACK,
+				(uint64_t)res, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+				FFA_PARAM_MBZ, result);
+			break;
+		case FFA_FRAMEWORK_MSG_VM_DESTROYED:
+			res = ffa_vm_destroyed_handler(vm_id, handle);
+			ffa_svc(FFA_MSG_SEND_DIRECT_RESP_32, ((uint32_t)dst_id << 16) | src_id,
+				FFA_MSG_FLAG_FRAMEWORK | FFA_FRAMEWORK_MSG_VM_DESTROYED_ACK,
+				(uint64_t)res, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
+				FFA_PARAM_MBZ, result);
+			break;
+		default:
+			ffa_svc(FFA_ERROR, FFA_PARAM_MBZ, FFA_INVALID_PARAMETERS, FFA_PARAM_MBZ,
+				FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, result);
+			break;
+		}
+	}
+}
+
 ffa_result ffa_msg_wait(struct ffa_direct_msg *msg)
 {
 	struct ffa_params result = {0};
@@ -220,9 +281,10 @@
 		FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
 		&result);
 
-	while (result.a0 == FFA_INTERRUPT) {
-		ffa_interrupt_handler(result.a2);
-		ffa_return_from_interrupt(&result);
+	/* FF-A framework messages are handled outside of the main partition message handler loop */
+	while ((result.a0 == FFA_INTERRUPT) ||
+		(result.a0 == FFA_MSG_SEND_DIRECT_REQ_32 && FFA_IS_FRAMEWORK_MSG(result.a2))) {
+		handle_framework_msg(&result);
 	}
 
 	if (result.a0 == FFA_ERROR) {
@@ -299,9 +361,10 @@
 		SHIFT_U32(source, FFA_MSG_SEND_DIRECT_RESP_SOURCE_ID_SHIFT) |
 		dest, FFA_PARAM_MBZ, a0, a1, a2, a3, a4, &result);
 
-	while (result.a0 == FFA_INTERRUPT) {
-		ffa_interrupt_handler(result.a2);
-		ffa_return_from_interrupt(&result);
+	/* FF-A framework messages are handled outside of the main partition message handler loop */
+	while ((result.a0 == FFA_INTERRUPT) ||
+		(result.a0 == FFA_MSG_SEND_DIRECT_REQ_32 && FFA_IS_FRAMEWORK_MSG(result.a2))) {
+		handle_framework_msg(&result);
 	}
 
 	if (result.a0 == FFA_ERROR) {
diff --git a/components/messaging/ffa/libsp/ffa_memory_descriptors.c b/components/messaging/ffa/libsp/ffa_memory_descriptors.c
index 6bf097d..41cf04d 100644
--- a/components/messaging/ffa/libsp/ffa_memory_descriptors.c
+++ b/components/messaging/ffa/libsp/ffa_memory_descriptors.c
@@ -60,6 +60,47 @@
 	return get_composite_desc_by_offset(buffer, offset);
 }
 
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+static struct ffa_mem_access_desc *get_mem_access_desc_by_offset(
+	struct ffa_mem_transaction_buffer *buffer, uint32_t offset)
+{
+	void *ptr = NULL;
+
+	assert(offset <= buffer->length);
+	ptr = (((uint8_t *)buffer->buffer) + offset);
+
+	return (struct ffa_mem_access_desc *)ptr;
+}
+#endif /* CFG_FFA_VERSION */
+
+struct ffa_mem_access_desc *get_mem_access_desc(struct ffa_mem_transaction_buffer *buffer,
+						uint32_t descriptor_index)
+{
+	struct ffa_mem_transaction_desc *transaction = NULL;
+	struct ffa_mem_access_desc *access_desc = NULL;
+	size_t offset = 0;
+	size_t __maybe_unused mem_desc_offset = 0;
+
+	transaction = get_mem_transaction_desc(buffer);
+
+	assert(descriptor_index < transaction->mem_access_desc_count);
+
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
+	access_desc = &transaction->mem_access_desc[descriptor_index];
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+	mem_desc_offset = transaction->mem_access_desc_offset;
+	mem_desc_offset += transaction->mem_access_desc_size * descriptor_index;
+	access_desc = get_mem_access_desc_by_offset(buffer, mem_desc_offset);
+#endif /* CFG_FFA_VERSION */
+
+	/* Validating if the whole descriptor is within the buffer boundaries */
+	offset = get_offset_in_buffer(buffer, access_desc);
+	offset += sizeof(struct ffa_mem_access_desc);
+	assert(offset <= buffer->length);
+
+	return access_desc;
+}
+
 void ffa_init_mem_transaction_buffer(void *address, size_t length,
 				     struct ffa_mem_transaction_buffer *buffer)
 {
@@ -69,24 +110,29 @@
 }
 
 void ffa_init_mem_transaction_desc(struct ffa_mem_transaction_buffer *buffer,
-				   uint16_t sender_id, uint8_t mem_region_attr,
-				   uint32_t flags, uint64_t handle,
-				   uint64_t tag)
+				   uint16_t sender_id, uint16_t mem_region_attr,
+				   uint32_t flags, uint64_t handle, uint64_t tag)
 {
 	struct ffa_mem_transaction_desc *transaction = NULL;
 
 	transaction = get_mem_transaction_desc(buffer);
 
+	memset(transaction, 0x00, sizeof(*transaction));
+
 	transaction->sender_id = sender_id;
 	transaction->mem_region_attr = mem_region_attr;
-	transaction->reserved_mbz0 = 0;
 	transaction->flags = flags;
 	transaction->handle = handle;
 	transaction->tag = tag;
-	transaction->reserved_mbz1 = 0;
 	transaction->mem_access_desc_count = 0;
 
-	buffer->used = sizeof(struct ffa_mem_transaction_desc);
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	transaction->mem_access_desc_size = sizeof(struct ffa_mem_access_desc);
+	/* The memory access descriptors start right after the transaction descriptor */
+	transaction->mem_access_desc_offset = sizeof(*transaction);
+#endif /* CFG_FFA_VERSION */
+
+	buffer->used = sizeof(*transaction);
 }
 
 const struct ffa_mem_transaction_desc *
@@ -126,9 +172,8 @@
 		buffer->used = required_size;
 }
 
-uint32_t ffa_add_mem_access_desc(struct ffa_mem_transaction_buffer *buffer,
-				 uint16_t endpoint_id, uint8_t mem_access_perm,
-				 uint8_t flags)
+uint32_t ffa_add_mem_access_desc(struct ffa_mem_transaction_buffer *buffer, uint16_t endpoint_id,
+				 uint8_t mem_access_perm, uint8_t flags)
 {
 	struct ffa_mem_transaction_desc *transaction = NULL;
 	struct ffa_mem_access_desc *access_desc = NULL;
@@ -136,6 +181,7 @@
 	uint32_t index = 0;
 	uint32_t composite_offset = 0;
 	size_t required_size = 0;
+	size_t __maybe_unused mem_desc_offset = 0;
 
 	/* Get next access descriptor index */
 	transaction = get_mem_transaction_desc(buffer);
@@ -144,7 +190,7 @@
 	assert(index != UINT32_MAX);
 
 	/* Allocating access descriptor */
-	required_size = sizeof(struct ffa_mem_transaction_desc);
+	required_size = sizeof(*transaction);
 	required_size += sizeof(struct ffa_mem_access_desc) * (index + 1);
 	assert(required_size <= buffer->length);
 
@@ -161,8 +207,13 @@
 	transaction->mem_access_desc_count++;
 
 	/* Initializing access descriptor */
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 	access_desc = &transaction->mem_access_desc[index];
-
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+	mem_desc_offset = transaction->mem_access_desc_offset;
+	mem_desc_offset += transaction->mem_access_desc_size * index;
+	access_desc = get_mem_access_desc_by_offset(buffer, mem_desc_offset);
+#endif
 	access_perm_desc = &access_desc->mem_access_perm_desc;
 	access_perm_desc->endpoint_id = endpoint_id;
 	access_perm_desc->mem_access_permissions = mem_access_perm;
@@ -190,33 +241,16 @@
 	return transaction->mem_access_desc_count;
 }
 
-const struct ffa_mem_access_desc *
-ffa_get_mem_access_desc(struct ffa_mem_transaction_buffer *buffer,
-			uint32_t descriptor_index)
+const struct ffa_mem_access_desc *ffa_get_mem_access_desc(struct ffa_mem_transaction_buffer *buffer,
+							  uint32_t descriptor_index)
 {
-	struct ffa_mem_transaction_desc *transaction = NULL;
-	struct ffa_mem_access_desc *access_desc = NULL;
-	size_t offset = 0;
-
-	transaction = get_mem_transaction_desc(buffer);
-
-	assert(descriptor_index < transaction->mem_access_desc_count);
-
-	access_desc = &transaction->mem_access_desc[descriptor_index];
-
-	/* Validating if the whole descriptor is within the buffer boundaries */
-	offset = get_offset_in_buffer(buffer, access_desc);
-	offset += sizeof(struct ffa_mem_access_desc);
-	assert(offset <= buffer->length);
-
-	return access_desc;
+	return get_mem_access_desc(buffer, descriptor_index);
 }
 
 void ffa_add_memory_region(struct ffa_mem_transaction_buffer *buffer,
 			   const void *address, uint32_t page_count)
 {
 	struct ffa_mem_transaction_desc *transaction = NULL;
-
 	struct ffa_composite_mem_region_desc *comp_desc = NULL;
 	struct ffa_constituent_mem_region_desc *region_desc = NULL;
 	size_t required_size = 0;
@@ -253,7 +287,7 @@
 		 * memory access descriptors
 		 */
 		for (i = 0; i < transaction->mem_access_desc_count; i++) {
-			access_desc = &transaction->mem_access_desc[i];
+			access_desc = get_mem_access_desc(buffer, i);
 			access_desc->composite_mem_region_desc_offset = offset;
 		}
 
diff --git a/components/messaging/ffa/libsp/include/ffa_api.h b/components/messaging/ffa/libsp/include/ffa_api.h
index e18e381..2175d8f 100644
--- a/components/messaging/ffa/libsp/include/ffa_api.h
+++ b/components/messaging/ffa/libsp/include/ffa_api.h
@@ -82,12 +82,14 @@
  */
 ffa_result ffa_rxtx_unmap(uint16_t id);
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 /**
- * @brief      Requests the SPM to return information about the partition of
+ * @brief      Requests the SPM to return information about the partitions of
  *             the system. Nil UUID can be used to return information about all
  *             the SPs of the system. The information is returned in the RX
  *             buffer of the caller as an array of ffa_partition_information
  *             structures.
+ *             This is an FF-A v1.0 call.
  *
  * @param[in]  uuid   The uuid
  * @param[out] count  Count of partition information descriptors populated in
@@ -96,6 +98,27 @@
  * @return     The FF-A error status code
  */
 ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t *count);
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+
+/**
+ * @brief      Requests the SPM to return information about the partitions of
+ *             the system. Nil UUID can be used to return information about all
+ *             the SPs of the system. The information is returned in the RX
+ *             buffer of the caller as an array of ffa_partition_information
+ *             structures.
+ *             By settings the flags parameter, the function can be instructed
+ *             to only return the count of SPs with the matching UUID.
+ *             This is an FF-A v1.1 call.
+ *
+ * @param[in]  uuid     The uuid
+ * @param[in]  flags	FFA_PARTITION_INFO_GET_FLAG_* flag value
+ * @param[out] count    Count of matching SPs
+ * @param[out] size     Size of the partition information descriptors
+ * @return ffa_result
+ */
+ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t flags,
+				  uint32_t *count, uint32_t *size);
+#endif /* CFG_FFA_VERSION */
 
 /**
  * @brief      Returns the 16 bit ID of the calling FF-A component
@@ -389,6 +412,28 @@
  */
 void ffa_interrupt_handler(uint32_t interrupt_id);
 
+/**
+ * @brief      VM created message handler prototype. Must be implemented by
+ *             another component.
+ *
+ * @param[in]  vm_id  ID of VM that has been created
+ * @param[in]  handle Globally unique Handle to identify a memory region that
+ *                    contains information associated with the created VM
+ * @return            The FF-A error status code
+ */
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle);
+
+/**
+ * @brief      VM destroyed message handler prototype. Must be implemented by
+ *             another component.
+ *
+ * @param[in]  vm_id  ID of VM that has been destroyed
+ * @param[in]  handle Globally unique Handle to identify a memory region that
+ *                    contains information associated with the destroyed VM
+ * @return            The FF-A error status code
+ */
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/messaging/ffa/libsp/include/ffa_api_defines.h b/components/messaging/ffa/libsp/include/ffa_api_defines.h
index e5aea41..23389a5 100644
--- a/components/messaging/ffa/libsp/include/ffa_api_defines.h
+++ b/components/messaging/ffa/libsp/include/ffa_api_defines.h
@@ -9,6 +9,15 @@
 #include <stdint.h>
 #include "util.h"
 
+#define FFA_VERSION_1_0	(0x00010000)
+#define FFA_VERSION_1_1	(0x00010001)
+
+#ifndef CFG_FFA_VERSION
+#error CFG_FFA_VERSION must be defined
+#elif CFG_FFA_VERSION != FFA_VERSION_1_0 && CFG_FFA_VERSION != FFA_VERSION_1_1
+#error Only FF-A versions 1.0 and 1.1 are supported
+#endif
+
 /* Status codes */
 #define FFA_OK				(0)
 #define FFA_NOT_SUPPORTED		(-1)
@@ -101,10 +110,16 @@
 #define FFA_BOOT_INFO_NAME_FMT_UUID	UINT32_C(1)
 
 /* FFA_VERSION */
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 #define FFA_VERSION_MAJOR		UINT32_C(1)
+#define FFA_VERSION_MINOR		UINT32_C(0)
+#elif CFG_FFA_VERSION == FFA_VERSION_1_1
+#define FFA_VERSION_MAJOR		UINT32_C(1)
+#define FFA_VERSION_MINOR		UINT32_C(1)
+#endif /* CFG_FFA_VERSION */
+
 #define FFA_VERSION_MAJOR_SHIFT		UINT32_C(16)
 #define FFA_VERSION_MAJOR_MASK		GENMASK_32(14, 0)
-#define FFA_VERSION_MINOR		UINT32_C(0)
 #define FFA_VERSION_MINOR_SHIFT		UINT32_C(0)
 #define FFA_VERSION_MINOR_MASK		GENMASK_32(15, 0)
 
@@ -139,9 +154,28 @@
 #define FFA_RXTX_UNMAP_ID_MASK				GENMASK_32(15, 0)
 
 /* FFA_PARTITION_INFO_GET */
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+#define FFA_PARTITION_INFO_GET_FLAG_COUNT_ONLY		BIT32(0)
+#endif /* CFG_FFA_VERSION */
+
 #define FFA_PARTITION_SUPPORTS_DIRECT_REQUESTS		BIT32(0)
 #define FFA_PARTITION_CAN_SEND_DIRECT_REQUESTS		BIT32(1)
 #define FFA_PARTITION_SUPPORTS_INDIRECT_REQUESTS	BIT32(2)
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+#define FFA_PARTITION_SUPPORTS_NOTIFICATIONS		BIT32(3)
+
+#define FFA_PARTITION_PART_ID_SHIFT			UINT32_C(4)
+#define FFA_PARTITION_PART_ID_MASK			GENMASK_32(1, 0)
+#define FFA_PARTITION_PART_ID_PE_ENDPOINT_ID		UINT16_C(0)
+#define FFA_PARTITION_PART_ID_SEPID_INDEPENDENT		UINT16_C(1)
+#define FFA_PARTITION_PART_ID_SEPID_DEPENDENT		UINT16_C(2)
+#define FFA_PARTITION_PART_ID_PE_AUX_ID			UINT16_C(3)
+
+#define FFA_PARTITION_INFORM_VM_CREATE			BIT32(6)
+#define FFA_PARTITION_INFORM_VM_DESTROY			BIT32(7)
+
+#define FFA_PARTITION_AARCH64_EXECUTION_STATE		BIT32(8)
+#endif /* CFG_FFA_VERSION */
 
 /* FFA_ID_GET */
 #define FFA_ID_GET_ID_SHIFT				UINT32_C(0)
@@ -161,6 +195,17 @@
 #define FFA_MSG_SEND_DIRECT_RESP_DEST_ID_MASK		GENMASK_32(15, 0)
 #define FFA_MSG_SEND_DIRECT_RESP_DEST_ID_SHIFT		UINT32_C(0)
 
+/* FF-A direct message flags */
+#define FFA_MSG_FLAG_FRAMEWORK				BIT32(31)
+#define FFA_FRAMEWORK_MSG_TYPE_SHIFT			UINT32_C(0)
+#define FFA_FRAMEWORK_MSG_TYPE_MASK			GENMASK_32(7, 0)
+#define FFA_FRAMEWORK_MSG_PSCI				UINT32_C(0x0)
+#define FFA_FRAMEWORK_MSG_VM_CREATED			UINT32_C(0x4)
+#define FFA_FRAMEWORK_MSG_VM_CREATED_ACK		UINT32_C(0x5)
+#define FFA_FRAMEWORK_MSG_VM_DESTROYED			UINT32_C(0x6)
+#define FFA_FRAMEWORK_MSG_VM_DESTROYED_ACK		UINT32_C(0x7)
+#define FFA_IS_FRAMEWORK_MSG(x)				(((x) & FFA_MSG_FLAG_FRAMEWORK) != 0)
+
 /* Table 5.15: Memory access permissions descriptor */
 
 /* Memory access permissions */
@@ -186,6 +231,10 @@
 #define FFA_MEM_REGION_ATTR_MEMORY_TYPE_MASK		GENMASK_32(1, 0)
 #define FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT		UINT32_C(4)
 
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+#define FFA_MEM_REGION_ATTR_NS_BIT			BIT32(6)
+#endif
+
 #define FFA_MEM_REGION_ATTR_MEMORY_TYPE_NOT_SPECIFIED	UINT32_C(0x00)
 #define FFA_MEM_REGION_ATTR_MEMORY_TYPE_DEVICE		UINT32_C(0x01)
 #define FFA_MEM_REGION_ATTR_MEMORY_TYPE_NORMAL		UINT32_C(0x02)
diff --git a/components/messaging/ffa/libsp/include/ffa_api_types.h b/components/messaging/ffa/libsp/include/ffa_api_types.h
index 7156c02..e067866 100644
--- a/components/messaging/ffa/libsp/include/ffa_api_types.h
+++ b/components/messaging/ffa/libsp/include/ffa_api_types.h
@@ -7,6 +7,7 @@
 #define LIBSP_INCLUDE_FFA_API_TYPES_H_
 
 #include "compiler.h"
+#include "ffa_api_defines.h"
 #include <stddef.h>
 #include <stdint.h>
 
@@ -90,12 +91,16 @@
 };
 
 /**
- * @brief Table 8.25: Partition information descriptor
+ * @brief Table 8.25: Partition information descriptor (FF-A v1.0)
+ *        Table 13.37: Partition information descriptor (FF-A v1.1)
  */
 struct ffa_partition_information {
 	uint16_t partition_id;
 	uint16_t execution_context_count;
 	uint32_t partition_properties;
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	struct ffa_uuid uuid;
+#endif
 } __packed;
 
 /**
@@ -156,8 +161,9 @@
 	uint64_t reserved_mbz;
 } __packed;
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 /**
- * @brief Table 5.19: Lend, donate or share memory transaction descriptor
+ * @brief FF-A v1.0 Table 5.19: Lend, donate or share memory transaction descriptor
  */
 struct ffa_mem_transaction_desc {
 	uint16_t sender_id;
@@ -170,6 +176,22 @@
 	uint32_t mem_access_desc_count;
 	struct ffa_mem_access_desc mem_access_desc[];
 } __packed;
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+/**
+ * @brief FF-A v1.1 Table 10.20: Memory transaction descriptor
+ */
+struct ffa_mem_transaction_desc {
+	uint16_t sender_id;
+	uint16_t mem_region_attr;
+	uint32_t flags;
+	uint64_t handle;
+	uint64_t tag;
+	uint32_t mem_access_desc_size;
+	uint32_t mem_access_desc_count;
+	uint32_t mem_access_desc_offset;
+	uint8_t reserved_mbz0[12];
+} __packed;
+#endif /* CFG_FFA_VERSION */
 
 /**
  * @brief Table 11.25: Descriptor to relinquish a memory region
diff --git a/components/messaging/ffa/libsp/include/ffa_memory_descriptors.h b/components/messaging/ffa/libsp/include/ffa_memory_descriptors.h
index 918a103..0491bf6 100644
--- a/components/messaging/ffa/libsp/include/ffa_memory_descriptors.h
+++ b/components/messaging/ffa/libsp/include/ffa_memory_descriptors.h
@@ -53,9 +53,8 @@
  * @param[in]  tag              Memory region tag
  */
 void ffa_init_mem_transaction_desc(struct ffa_mem_transaction_buffer *buffer,
-				   uint16_t sender_id, uint8_t mem_region_attr,
-				   uint32_t flags, uint64_t handle,
-				   uint64_t tag);
+				   uint16_t sender_id, uint16_t mem_region_attr,
+				   uint32_t flags, uint64_t handle, uint64_t tag);
 
 /**
  * @brief      Queries the memory transaction descriptor (see Table 5.19) from
diff --git a/components/messaging/ffa/libsp/include/sp_discovery.h b/components/messaging/ffa/libsp/include/sp_discovery.h
index 977c875..968aee8 100644
--- a/components/messaging/ffa/libsp/include/sp_discovery.h
+++ b/components/messaging/ffa/libsp/include/sp_discovery.h
@@ -19,12 +19,33 @@
 	uint8_t uuid[16];
 };
 
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+enum sp_partition_id_type {
+	sp_partition_id_type_pe_endpoint_id = 0,
+	sp_partition_id_type_sepid_independent,
+	sp_partition_id_type_sepid_dependent,
+	sp_partition_id_type_auxiliary_id
+};
+
+enum sp_execution_state {
+	sp_execution_state_aarch32 = 0,
+	sp_execution_state_aarch64,
+};
+#endif /* CFG_FFA_VERSION */
+
 struct sp_partition_info {
 	uint16_t partition_id;
 	uint16_t execution_context_count;
 	bool supports_direct_requests;
 	bool can_send_direct_requests;
 	bool supports_indirect_requests;
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	enum sp_partition_id_type partition_id_type;
+	bool inform_vm_create;
+	bool inform_vm_destroy;
+	enum sp_execution_state execution_state;
+	struct sp_uuid uuid;
+#endif /* CFG_FFA_VERSION */
 };
 
 /**
@@ -87,6 +108,19 @@
 sp_result sp_discovery_partition_info_get_all(struct sp_partition_info info[],
 					      uint32_t *count);
 
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+/**
+ * @brief          Queries the count of partitions.
+ *
+ * @param[in]      uuid  The UUID of the partition
+ * @param[out]     count The count of matching partitions
+ *
+ * @return         The SP API result
+ */
+sp_result sp_discovery_partition_info_get_count(const struct sp_uuid *uuid,
+						uint32_t *count);
+#endif /* CFG_FFA_VERSION */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/messaging/ffa/libsp/include/sp_memory_management.h b/components/messaging/ffa/libsp/include/sp_memory_management.h
index ec76a3d..1ba2437 100644
--- a/components/messaging/ffa/libsp/include/sp_memory_management.h
+++ b/components/messaging/ffa/libsp/include/sp_memory_management.h
@@ -23,6 +23,16 @@
 extern "C" {
 #endif
 
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+/**
+ * @brief      Security state of the memory region
+ */
+enum sp_memory_security_state {
+	sp_memory_security_state_secure = 0x00,
+	sp_memory_security_state_non_secure = 0x01,
+};
+#endif /* CFG_FFA_VERSION */
+
 /**
  * @brief      Memory type of the region
  */
@@ -111,6 +121,11 @@
 
 	/** Device memory attributes */
 	enum sp_device_memory_attributes device_memory;
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	/* Memory security state (secure/non-secure) */
+	enum sp_memory_security_state security_state;
+#endif /* CFG_FFA_VERSION */
 };
 
 /**
diff --git a/components/messaging/ffa/libsp/mock/component.cmake b/components/messaging/ffa/libsp/mock/component.cmake
index 375cb46..101a56f 100644
--- a/components/messaging/ffa/libsp/mock/component.cmake
+++ b/components/messaging/ffa/libsp/mock/component.cmake
@@ -8,6 +8,8 @@
 	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
 endif()
 
+set(CFG_FFA_VERSION 0x00010001 CACHE STRING "The supported FF-A protocol's version: (major << 16) | minor")
+
 target_sources(${TGT} PRIVATE
 	"${CMAKE_CURRENT_LIST_DIR}/mock_assert.cpp"
 	"${CMAKE_CURRENT_LIST_DIR}/mock_ffa_api.cpp"
@@ -27,4 +29,5 @@
 target_compile_definitions(${TGT}
 	PUBLIC
 		"ARM64=1"
+		"CFG_FFA_VERSION=${CFG_FFA_VERSION}"
 )
\ No newline at end of file
diff --git a/components/messaging/ffa/libsp/mock/mock_ffa_api.cpp b/components/messaging/ffa/libsp/mock/mock_ffa_api.cpp
index 38637cf..f3cd0f5 100644
--- a/components/messaging/ffa/libsp/mock/mock_ffa_api.cpp
+++ b/components/messaging/ffa/libsp/mock/mock_ffa_api.cpp
@@ -90,6 +90,7 @@
 		.returnIntValue();
 }
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 void expect_ffa_partition_info_get(const struct ffa_uuid *uuid,
 				   const uint32_t *count, ffa_result result)
 {
@@ -109,6 +110,31 @@
 		.withOutputParameter("count", count)
 		.returnIntValue();
 }
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+void expect_ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t flags,
+				   const uint32_t *count, const uint32_t *size,
+				   ffa_result result)
+{
+	mock().expectOneCall("ffa_partition_info_get")
+		.withMemoryBufferParameter("uuid", (const unsigned char *)uuid, sizeof(*uuid))
+		.withUnsignedIntParameter("flags", flags)
+		.withOutputParameterReturning("count", count, sizeof(*count))
+		.withOutputParameterReturning("size", size, sizeof(*size))
+		.andReturnValue(result);
+}
+
+ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t flags, uint32_t *count,
+				  uint32_t *size)
+{
+	return mock()
+		.actualCall("ffa_partition_info_get")
+		.withMemoryBufferParameter("uuid", (const unsigned char *)uuid, sizeof(*uuid))
+		.withUnsignedIntParameter("flags", flags)
+		.withOutputParameter("count", count)
+		.withOutputParameter("size", size)
+		.returnIntValue();
+}
+#endif /* CFG_FFA_VERSION */
 
 void expect_ffa_id_get(const uint16_t *id, ffa_result result)
 {
diff --git a/components/messaging/ffa/libsp/mock/mock_ffa_api.h b/components/messaging/ffa/libsp/mock/mock_ffa_api.h
index 9c3dbc8..10dafcd 100644
--- a/components/messaging/ffa/libsp/mock/mock_ffa_api.h
+++ b/components/messaging/ffa/libsp/mock/mock_ffa_api.h
@@ -23,8 +23,14 @@
 
 void expect_ffa_rxtx_unmap(uint16_t id, ffa_result result);
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 void expect_ffa_partition_info_get(const struct ffa_uuid *uuid,
 				   const uint32_t *count, ffa_result result);
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+void expect_ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t flags,
+				   const uint32_t *count, const uint32_t *size,
+				   ffa_result result);
+#endif /* CFG_FFA_VERSION */
 
 void expect_ffa_id_get(const uint16_t *id, ffa_result result);
 
diff --git a/components/messaging/ffa/libsp/mock/test/test_mock_ffa_api.cpp b/components/messaging/ffa/libsp/mock/test/test_mock_ffa_api.cpp
index 8b793d3..f85c816 100644
--- a/components/messaging/ffa/libsp/mock/test/test_mock_ffa_api.cpp
+++ b/components/messaging/ffa/libsp/mock/test/test_mock_ffa_api.cpp
@@ -73,18 +73,37 @@
 	LONGS_EQUAL(result, ffa_rxtx_unmap(id));
 }
 
-TEST(mock_ffa_api, ffa_partition_info_get)
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
+TEST(mock_ffa_api, ffa_partition_info_get_v1_0)
 {
 	const struct ffa_uuid uuid = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
 				       0x32, 0x10, 0x01, 0x23, 0x45, 0x67,
 				       0x89, 0xab, 0xcd, 0xef };
-	const uint32_t expect_count = 0xff00ee11U;
+	const uint32_t expected_count = 0xff00ee11U;
 	uint32_t count = 0;
 
-	expect_ffa_partition_info_get(&uuid, &expect_count, result);
+	expect_ffa_partition_info_get(&uuid, &expected_count, result);
 	LONGS_EQUAL(result, ffa_partition_info_get(&uuid, &count));
-	UNSIGNED_LONGS_EQUAL(expect_count, count);
+	UNSIGNED_LONGS_EQUAL(expected_count, count);
 }
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+TEST(mock_ffa_api, ffa_partition_info_get_v1_1)
+{
+	const struct ffa_uuid uuid = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54,
+				       0x32, 0x10, 0x01, 0x23, 0x45, 0x67,
+				       0x89, 0xab, 0xcd, 0xef };
+	const uint32_t flags = 0xabcdef01;
+	const uint32_t expected_count = 0xff00ee11U;
+	const uint32_t expected_size = 0xff00ee11U;
+	uint32_t count = 0;
+	uint32_t size = 0;
+
+	expect_ffa_partition_info_get(&uuid, flags, &expected_count, &expected_size, result);
+	LONGS_EQUAL(result, ffa_partition_info_get(&uuid, flags, &count, &size));
+	UNSIGNED_LONGS_EQUAL(expected_count, count);
+	UNSIGNED_LONGS_EQUAL(expected_size, size);
+}
+#endif /* CFG_FFA_VERSION */
 
 TEST(mock_ffa_api, ffa_id_get)
 {
diff --git a/components/messaging/ffa/libsp/sp_discovery.c b/components/messaging/ffa/libsp/sp_discovery.c
index 7f92b6b..cbe66ce 100644
--- a/components/messaging/ffa/libsp/sp_discovery.c
+++ b/components/messaging/ffa/libsp/sp_discovery.c
@@ -51,13 +51,22 @@
 		props & FFA_PARTITION_CAN_SEND_DIRECT_REQUESTS;
 	sp_info->supports_indirect_requests =
 		props & FFA_PARTITION_SUPPORTS_INDIRECT_REQUESTS;
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	sp_info->partition_id_type =
+		(props >> FFA_PARTITION_PART_ID_SHIFT) & FFA_PARTITION_PART_ID_MASK;
+	sp_info->inform_vm_create = props & FFA_PARTITION_INFORM_VM_CREATE;
+	sp_info->inform_vm_destroy = props & FFA_PARTITION_INFORM_VM_DESTROY;
+	if (props & FFA_PARTITION_AARCH64_EXECUTION_STATE)
+		sp_info->execution_state = sp_execution_state_aarch64;
+	else
+		sp_info->execution_state = sp_execution_state_aarch32;
+	memcpy(sp_info->uuid.uuid, ffa_info->uuid.uuid, sizeof(sp_info->uuid.uuid));
+
+#endif /* CFG_FFA_VERSION */
 }
 
-static sp_result
-partition_info_get(const struct sp_uuid *uuid,
-		   struct sp_partition_info info[],
-		   uint32_t *count,
-		   bool allow_nil_uuid)
+static sp_result partition_info_get(const struct sp_uuid *uuid, struct sp_partition_info info[],
+				    uint32_t *count, bool allow_nil_uuid)
 {
 	const struct ffa_partition_information *ffa_info = NULL;
 	uint32_t ffa_count = 0;
@@ -67,6 +76,7 @@
 	size_t buffer_size = 0;
 	struct ffa_uuid ffa_uuid = { 0 };
 	ffa_result ffa_res = FFA_OK;
+	uint32_t __maybe_unused ffa_size = 0;
 
 	if (count == NULL)
 		return SP_RESULT_INVALID_PARAMETERS;
@@ -90,17 +100,28 @@
 	/* Safely convert to FF-A UUID format */
 	memcpy(&ffa_uuid.uuid, uuid->uuid, sizeof(ffa_uuid.uuid));
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 	ffa_res = ffa_partition_info_get(&ffa_uuid, &ffa_count);
 	if (ffa_res != FFA_OK) {
 		sp_res = SP_RESULT_FFA(ffa_res);
 		goto out;
 	}
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+	ffa_res = ffa_partition_info_get(&ffa_uuid, 0, &ffa_count, &ffa_size);
+	if (ffa_res != FFA_OK) {
+		sp_res = SP_RESULT_FFA(ffa_res);
+		goto out;
+	}
+
+	if (ffa_size != sizeof(struct ffa_partition_information)) {
+		/* Non-matching structure size, this may happen in future FF-A versions */
+		sp_res = SP_RESULT_INTERNAL_ERROR;
+		goto out;
+	}
+#endif
 
 	if ((ffa_count * sizeof(struct ffa_partition_information)) > buffer_size) {
-		/*
-		 * The indicated amount of info structures doesn't fit into the
-		 * RX buffer.
-		 */
+		/* The indicated amount of info structures doesn't fit into the RX buffer */
 		sp_res = SP_RESULT_INTERNAL_ERROR;
 		goto out;
 	}
@@ -162,3 +183,34 @@
 {
 	return partition_info_get(&uuid_nil, info, count, true);
 }
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+sp_result sp_discovery_partition_info_get_count(const struct sp_uuid *uuid, uint32_t *count)
+{
+	struct ffa_uuid ffa_uuid = { 0 };
+	ffa_result ffa_res = FFA_OK;
+	uint32_t ffa_size = 0;
+
+	if (count == NULL)
+		return SP_RESULT_INVALID_PARAMETERS;
+
+	*count = 0;
+
+	if (uuid == NULL)
+		return SP_RESULT_INVALID_PARAMETERS;
+
+	/* Safely convert to FF-A UUID format */
+	memcpy(&ffa_uuid.uuid, uuid->uuid, sizeof(ffa_uuid.uuid));
+
+	ffa_res = ffa_partition_info_get(&ffa_uuid, FFA_PARTITION_INFO_GET_FLAG_COUNT_ONLY, count,
+					 &ffa_size);
+	if (ffa_res != FFA_OK)
+		return SP_RESULT_FFA(ffa_res);
+
+	if (ffa_size != 0)
+		/* Size is MBZ if FFA_PARTITION_INFO_GET_FLAG_COUNT_ONLY is set */
+		return SP_RESULT_INTERNAL_ERROR;
+
+	return SP_RESULT_OK;
+}
+#endif /* CFG_FFA_VERSION */
diff --git a/components/messaging/ffa/libsp/sp_memory_management.c b/components/messaging/ffa/libsp/sp_memory_management.c
index 3dbeb61..8569c11 100644
--- a/components/messaging/ffa/libsp/sp_memory_management.c
+++ b/components/messaging/ffa/libsp/sp_memory_management.c
@@ -49,10 +49,10 @@
 	       !(((uintptr_t)buffer->length) & FFA_MEM_TRANSACTION_PAGE_MASK);
 }
 
-static uint8_t build_mem_region_attr(enum sp_memory_type type,
+static uint16_t build_mem_region_attr(enum sp_memory_type type,
 				     union sp_memory_attr *sp_mem_attr)
 {
-	uint8_t mem_attr = 0;
+	uint16_t mem_attr = 0;
 
 	assert(type != sp_memory_type_reserved);
 	mem_attr = SHIFT_U32(type, FFA_MEM_REGION_ATTR_MEMORY_TYPE_SHIFT);
@@ -80,10 +80,15 @@
 				      FFA_MEM_REGION_ATTR_SHAREABILITY_SHIFT);
 	}
 
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	if (sp_mem_attr->security_state == sp_memory_security_state_non_secure)
+		mem_attr |= FFA_MEM_REGION_ATTR_NS_BIT;
+#endif /* CFG_FFA_VERSION */
+
 	return mem_attr;
 }
 
-static void parse_mem_region_attr(uint8_t attr, enum sp_memory_type *type,
+static void parse_mem_region_attr(uint16_t attr, enum sp_memory_type *type,
 				  union sp_memory_attr *sp_mem_attr)
 {
 	uint8_t temp = 0;
@@ -113,6 +118,13 @@
 		       FFA_MEM_REGION_ATTR_SHAREABILITY_MASK;
 		norm_attr->shareability = (enum sp_shareablity_attribute)temp;
 	}
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	if (attr & FFA_MEM_REGION_ATTR_NS_BIT)
+		sp_mem_attr->security_state = sp_memory_security_state_non_secure;
+	else
+		sp_mem_attr->security_state = sp_memory_security_state_secure;
+#endif /* CFG_FFA_VERSION */
 }
 
 static uint8_t
@@ -205,7 +217,7 @@
 			      struct sp_memory_region regions[],
 			      uint32_t region_count, uint64_t handle)
 {
-	uint8_t mem_region_attr = 0;
+	uint16_t mem_region_attr = 0;
 	uint8_t acc_perm = 0;
 	uint32_t flags = 0;
 	uint32_t i = 0;
@@ -247,7 +259,7 @@
 	const struct ffa_mem_transaction_desc *transaction = NULL;
 	const struct ffa_mem_access_desc *acc = NULL;
 	const struct ffa_composite_mem_region_desc *region_desc = NULL;
-	uint8_t region_attr = 0;
+	uint16_t region_attr = 0;
 	uint8_t acc_perm = 0;
 
 	transaction = ffa_get_mem_transaction_desc(buffer);
diff --git a/components/messaging/ffa/libsp/test/test_ffa_api.cpp b/components/messaging/ffa/libsp/test/test_ffa_api.cpp
index 8395662..9660599 100644
--- a/components/messaging/ffa/libsp/test/test_ffa_api.cpp
+++ b/components/messaging/ffa/libsp/test/test_ffa_api.cpp
@@ -23,6 +23,38 @@
 		.withUnsignedIntParameter("id", id);
 }
 
+void expect_ffa_vm_created_handler(uint16_t vm_id, uint64_t handle, ffa_result result)
+{
+	mock().expectOneCall("ffa_vm_created_handler")
+		.withUnsignedIntParameter("vm_id", vm_id)
+		.withUnsignedLongIntParameter("handle", handle)
+		.andReturnValue(result);
+}
+
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	return mock().actualCall("ffa_vm_created_handler")
+		.withUnsignedIntParameter("vm_id", vm_id)
+		.withUnsignedLongIntParameter("handle", handle)
+		.returnIntValue();
+}
+
+void expect_ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle, ffa_result result)
+{
+	mock().expectOneCall("ffa_vm_destroyed_handler")
+		.withUnsignedIntParameter("vm_id", vm_id)
+		.withUnsignedLongIntParameter("handle", handle)
+		.andReturnValue(result);
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	return mock().actualCall("ffa_vm_destroyed_handler")
+		.withUnsignedIntParameter("vm_id", vm_id)
+		.withUnsignedLongIntParameter("handle", handle)
+		.returnIntValue();
+}
+
 TEST_GROUP(ffa_api)
 {
 	TEST_SETUP()
@@ -80,9 +112,14 @@
 {
 	uint32_t version = 0;
 	const uint32_t test_version = 0x78901234;
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
+	const uint32_t cfg_ffa_version = 0x00010000;
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+	const uint32_t cfg_ffa_version = 0x00010001;
+#endif /* CFG_FFA_VERSION */
 
 	svc_result.a0 = test_version;
-	expect_ffa_svc(0x84000063, 0x10000U, 0, 0, 0, 0, 0, 0, &svc_result);
+	expect_ffa_svc(0x84000063, cfg_ffa_version, 0, 0, 0, 0, 0, 0, &svc_result);
 
 	ffa_result result = ffa_version(&version);
 	LONGS_EQUAL(FFA_OK, result);
@@ -92,9 +129,14 @@
 TEST(ffa_api, ffa_version_error)
 {
 	uint32_t version = 0;
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
+	const uint32_t cfg_ffa_version = 0x00010000;
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+	const uint32_t cfg_ffa_version = 0x00010001;
+#endif /* CFG_FFA_VERSION */
 
 	svc_result.a0 = 0xffffffff;
-	expect_ffa_svc(0x84000063, 0x10000U, 0, 0, 0, 0, 0, 0, &svc_result);
+	expect_ffa_svc(0x84000063, cfg_ffa_version, 0, 0, 0, 0, 0, 0, &svc_result);
 
 	ffa_result result = ffa_version(&version);
 	LONGS_EQUAL(-1, result);
@@ -277,6 +319,7 @@
 	}
 }
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 TEST(ffa_api, ffa_partition_info_get)
 {
 	const struct ffa_uuid uuid = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
@@ -329,6 +372,70 @@
 		ffa_partition_info_get(&uuid, &count);
 	}
 }
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+TEST(ffa_api, ffa_partition_info_get)
+{
+	const struct ffa_uuid uuid = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
+				       0xcd, 0xef, 0x12, 0x34, 0x56, 0x78,
+				       0x9a, 0xbc, 0xde, 0xf0 };
+	const uint32_t flags = 0x33445566;
+	uint32_t count = 0;
+	uint32_t size = 0;
+	const uint32_t count_result = 0xaabbccdd;
+	const uint32_t size_result = 0xeeff1122;
+
+	svc_result.a0 = 0x84000061;
+	svc_result.a2 = count_result;
+	svc_result.a3 = size_result;
+	expect_ffa_svc(0x84000068, 0x67452301, 0xefcdab89, 0x78563412,
+		       0xf0debc9a, flags, 0, 0, &svc_result);
+
+	ffa_result result = ffa_partition_info_get(&uuid, flags, &count, &size);
+	LONGS_EQUAL(FFA_OK, result);
+	UNSIGNED_LONGS_EQUAL(count_result, count);
+	UNSIGNED_LONGS_EQUAL(size_result, size);
+}
+
+TEST(ffa_api, ffa_partition_info_get_error)
+{
+	const struct ffa_uuid uuid = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
+				       0xcd, 0xef, 0x12, 0x34, 0x56, 0x78,
+				       0x9a, 0xbc, 0xde, 0xf0 };
+	const uint32_t flags = 0x33445566;
+	uint32_t count = 0x1234;
+	uint32_t size = 0x5678;
+
+	setup_error_response(-1);
+	expect_ffa_svc(0x84000068, 0x67452301, 0xefcdab89, 0x78563412,
+		       0xf0debc9a, flags, 0, 0, &svc_result);
+
+	ffa_result result = ffa_partition_info_get(&uuid, flags, &count, &size);
+	LONGS_EQUAL(-1, result);
+	UNSIGNED_LONGS_EQUAL(0, count);
+	UNSIGNED_LONGS_EQUAL(0, size);
+}
+
+TEST(ffa_api, ffa_partition_info_get_unknown_response)
+{
+	const struct ffa_uuid uuid = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab,
+				       0xcd, 0xef, 0x12, 0x34, 0x56, 0x78,
+				       0x9a, 0xbc, 0xde, 0xf0 };
+	const uint32_t flags = 0x33445566;
+	uint32_t count = 0;
+	uint32_t size = 0;
+	const uint32_t count_result = 0xaabbccdd;
+	assert_environment_t assert_env;
+
+	svc_result.a0 = 0x12345678;
+	svc_result.a2 = count_result;
+	expect_ffa_svc(0x84000068, 0x67452301, 0xefcdab89, 0x78563412,
+		       0xf0debc9a, flags, 0, 0, &svc_result);
+
+	if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
+		ffa_partition_info_get(&uuid, flags, &count, &size);
+	}
+}
+#endif /* CFG_FFA_VERSION */
 
 TEST(ffa_api, ffa_id_get)
 {
@@ -476,6 +583,157 @@
 	msg_equal_32(0x84000061, 0, 0, 0, 0, 0, 0, 0);
 }
 
+TEST(ffa_api, ffa_msg_wait_vm_created_success)
+{
+	const uint16_t source_id = 0;
+	const uint16_t dest_id = 0x8001;
+	const uint16_t vm_id = 0x1234;
+	const uint64_t handle = 0x0123456789abcdefULL;
+	const uint32_t handle_hi = 0x01234567;
+	const uint32_t handle_lo = 0x89abcdef;
+	struct ffa_params vm_created_msg;
+
+	vm_created_msg.a0 = 0x8400006F;
+	vm_created_msg.a1 = ((uint32_t)source_id << 16) | dest_id;
+	vm_created_msg.a2 = FFA_MSG_FLAG_FRAMEWORK |
+			(FFA_FRAMEWORK_MSG_VM_CREATED << FFA_FRAMEWORK_MSG_TYPE_SHIFT);
+	vm_created_msg.a3 = handle_lo;
+	vm_created_msg.a4 = handle_hi;
+	vm_created_msg.a5 = vm_id;
+	expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &vm_created_msg);
+	expect_ffa_vm_created_handler(vm_id, handle, FFA_OK);
+
+	svc_result.a0 = 0x84000061;
+	expect_ffa_svc(0x84000070, ((uint32_t)dest_id) << 16 | source_id, FFA_MSG_FLAG_FRAMEWORK |
+		       (FFA_FRAMEWORK_MSG_VM_CREATED_ACK << FFA_FRAMEWORK_MSG_TYPE_SHIFT), 0, 0,
+		       0, 0, 0, &svc_result);
+
+	ffa_result result = ffa_msg_wait(&msg);
+	LONGS_EQUAL(0, result);
+	msg_equal_32(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_wait_vm_destroyed_success)
+{
+	const uint16_t source_id = 0;
+	const uint16_t dest_id = 0x8001;
+	const uint16_t vm_id = 0x1234;
+	const uint64_t handle = 0x0123456789abcdefULL;
+	const uint32_t handle_hi = 0x01234567;
+	const uint32_t handle_lo = 0x89abcdef;
+	struct ffa_params vm_destroyed_msg;
+
+	vm_destroyed_msg.a0 = 0x8400006F;
+	vm_destroyed_msg.a1 = ((uint32_t)source_id << 16) | dest_id;
+	vm_destroyed_msg.a2 = FFA_MSG_FLAG_FRAMEWORK |
+			(FFA_FRAMEWORK_MSG_VM_DESTROYED << FFA_FRAMEWORK_MSG_TYPE_SHIFT);
+	vm_destroyed_msg.a3 = handle_lo;
+	vm_destroyed_msg.a4 = handle_hi;
+	vm_destroyed_msg.a5 = vm_id;
+	expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &vm_destroyed_msg);
+	expect_ffa_vm_destroyed_handler(vm_id, handle, FFA_OK);
+
+	svc_result.a0 = 0x84000061;
+	expect_ffa_svc(0x84000070, ((uint32_t)dest_id) << 16 | source_id, FFA_MSG_FLAG_FRAMEWORK |
+		       (FFA_FRAMEWORK_MSG_VM_DESTROYED_ACK << FFA_FRAMEWORK_MSG_TYPE_SHIFT), 0, 0,
+		       0, 0, 0, &svc_result);
+
+	ffa_result result = ffa_msg_wait(&msg);
+	LONGS_EQUAL(0, result);
+	msg_equal_32(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_wait_vm_created_destroyed_success)
+{
+	const uint16_t source_id = 0;
+	const uint16_t dest_id = 0x8001;
+	const uint16_t vm_id = 0x1234;
+	const uint64_t handle = 0x0123456789abcdefULL;
+	const uint32_t handle_hi = 0x01234567;
+	const uint32_t handle_lo = 0x89abcdef;
+	struct ffa_params vm_created_msg;
+	struct ffa_params vm_destroyed_msg;
+
+	vm_created_msg.a0 = 0x8400006F;
+	vm_created_msg.a1 = ((uint32_t)source_id << 16) | dest_id;
+	vm_created_msg.a2 = FFA_MSG_FLAG_FRAMEWORK |
+			(FFA_FRAMEWORK_MSG_VM_CREATED << FFA_FRAMEWORK_MSG_TYPE_SHIFT);
+	vm_created_msg.a3 = handle_lo;
+	vm_created_msg.a4 = handle_hi;
+	vm_created_msg.a5 = vm_id;
+	expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &vm_created_msg);
+	expect_ffa_vm_created_handler(vm_id, handle, FFA_OK);
+
+	vm_destroyed_msg.a0 = 0x8400006F;
+	vm_destroyed_msg.a1 = ((uint32_t)source_id << 16) | dest_id;
+	vm_destroyed_msg.a2 = FFA_MSG_FLAG_FRAMEWORK |
+			(FFA_FRAMEWORK_MSG_VM_DESTROYED << FFA_FRAMEWORK_MSG_TYPE_SHIFT);
+	vm_destroyed_msg.a3 = handle_lo;
+	vm_destroyed_msg.a4 = handle_hi;
+	vm_destroyed_msg.a5 = vm_id;
+	expect_ffa_svc(0x84000070, ((uint32_t)dest_id) << 16 | source_id, FFA_MSG_FLAG_FRAMEWORK |
+		       (FFA_FRAMEWORK_MSG_VM_CREATED_ACK << FFA_FRAMEWORK_MSG_TYPE_SHIFT), 0, 0,
+		       0, 0, 0, &vm_destroyed_msg);
+	expect_ffa_vm_destroyed_handler(vm_id, handle, FFA_OK);
+
+	svc_result.a0 = 0x84000061;
+	expect_ffa_svc(0x84000070, ((uint32_t)dest_id) << 16 | source_id, FFA_MSG_FLAG_FRAMEWORK |
+		       (FFA_FRAMEWORK_MSG_VM_DESTROYED_ACK << FFA_FRAMEWORK_MSG_TYPE_SHIFT), 0, 0,
+		       0, 0, 0, &svc_result);
+	ffa_result result = ffa_msg_wait(&msg);
+	LONGS_EQUAL(0, result);
+	msg_equal_32(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
+TEST(ffa_api, ffa_msg_wait_vm_created_interrupt_destroyed_success)
+{
+	const uint16_t source_id = 0;
+	const uint16_t dest_id = 0x8001;
+	const uint16_t vm_id = 0x1234;
+	const uint64_t handle = 0x0123456789abcdefULL;
+	const uint32_t handle_hi = 0x01234567;
+	const uint32_t handle_lo = 0x89abcdef;
+	const uint32_t interrupt_id = 0x12345678;
+	struct ffa_params vm_created_msg;
+	struct ffa_params vm_destroyed_msg;
+	struct ffa_params interrupt_params;
+
+	vm_created_msg.a0 = 0x8400006F;
+	vm_created_msg.a1 = ((uint32_t)source_id << 16) | dest_id;
+	vm_created_msg.a2 = FFA_MSG_FLAG_FRAMEWORK |
+			(FFA_FRAMEWORK_MSG_VM_CREATED << FFA_FRAMEWORK_MSG_TYPE_SHIFT);
+	vm_created_msg.a3 = handle_lo;
+	vm_created_msg.a4 = handle_hi;
+	vm_created_msg.a5 = vm_id;
+	expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &vm_created_msg);
+	expect_ffa_vm_created_handler(vm_id, handle, FFA_OK);
+
+	interrupt_params.a0 = 0x84000062;
+	interrupt_params.a2 = interrupt_id;
+	expect_ffa_svc(0x84000070, ((uint32_t)dest_id) << 16 | source_id, FFA_MSG_FLAG_FRAMEWORK |
+		       (FFA_FRAMEWORK_MSG_VM_CREATED_ACK << FFA_FRAMEWORK_MSG_TYPE_SHIFT), 0, 0,
+		       0, 0, 0, &interrupt_params);
+	expect_ffa_interrupt_handler(interrupt_id);
+
+	vm_destroyed_msg.a0 = 0x8400006F;
+	vm_destroyed_msg.a1 = ((uint32_t)source_id << 16) | dest_id;
+	vm_destroyed_msg.a2 = FFA_MSG_FLAG_FRAMEWORK |
+			(FFA_FRAMEWORK_MSG_VM_DESTROYED << FFA_FRAMEWORK_MSG_TYPE_SHIFT);
+	vm_destroyed_msg.a3 = handle_lo;
+	vm_destroyed_msg.a4 = handle_hi;
+	vm_destroyed_msg.a5 = vm_id;
+	expect_ffa_svc(0x8400006B, 0, 0, 0, 0, 0, 0, 0, &vm_destroyed_msg);
+	expect_ffa_vm_destroyed_handler(vm_id, handle, FFA_OK);
+
+	svc_result.a0 = 0x84000061;
+	expect_ffa_svc(0x84000070, ((uint32_t)dest_id) << 16 | source_id, FFA_MSG_FLAG_FRAMEWORK |
+		       (FFA_FRAMEWORK_MSG_VM_DESTROYED_ACK << FFA_FRAMEWORK_MSG_TYPE_SHIFT), 0, 0,
+		       0, 0, 0, &svc_result);
+	ffa_result result = ffa_msg_wait(&msg);
+	LONGS_EQUAL(0, result);
+	msg_equal_32(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
 TEST(ffa_api, ffa_msg_wait_unknown_response)
 {
 	assert_environment_t assert_env;
@@ -971,6 +1229,43 @@
 	msg_equal_32(0x84000061, 0, 0, 0, 0, 0, 0, 0);
 }
 
+TEST(ffa_api, ffa_msg_send_direct_resp_32_vm_created_success)
+{
+	const uint16_t source_id = 0x1122;
+	const uint16_t dest_id = 0x3344;
+	const uint16_t nwd_id = 0;
+	const uint32_t arg0 = 0x01234567ULL;
+	const uint32_t arg1 = 0x12345678ULL;
+	const uint32_t arg2 = 0x23456789ULL;
+	const uint32_t arg3 = 0x3456789aULL;
+	const uint32_t arg4 = 0x456789abULL;
+	const uint16_t vm_id = 0x1234;
+	const uint64_t handle = 0x0123456789abcdefULL;
+	const uint32_t handle_hi = 0x01234567;
+	const uint32_t handle_lo = 0x89abcdef;
+	struct ffa_params vm_created_msg;
+
+	vm_created_msg.a0 = 0x8400006F;
+	vm_created_msg.a1 = ((uint32_t)nwd_id << 16) | source_id;
+	vm_created_msg.a2 = FFA_MSG_FLAG_FRAMEWORK |
+			(FFA_FRAMEWORK_MSG_VM_CREATED << FFA_FRAMEWORK_MSG_TYPE_SHIFT);
+	vm_created_msg.a3 = handle_lo;
+	vm_created_msg.a4 = handle_hi;
+	vm_created_msg.a5 = vm_id;
+	expect_ffa_svc(0x84000070, ((uint32_t)source_id << 16) | dest_id, 0,
+		       arg0, arg1, arg2, arg3, arg4, &vm_created_msg);
+	expect_ffa_vm_created_handler(vm_id, handle, FFA_OK);
+
+	svc_result.a0 = 0x84000061;
+	expect_ffa_svc(0x84000070, ((uint32_t)source_id) << 16 | nwd_id, FFA_MSG_FLAG_FRAMEWORK |
+		       (FFA_FRAMEWORK_MSG_VM_CREATED_ACK << FFA_FRAMEWORK_MSG_TYPE_SHIFT), 0, 0,
+		       0, 0, 0, &svc_result);
+	ffa_result result = ffa_msg_send_direct_resp_32(
+		source_id, dest_id, arg0, arg1, arg2, arg3, arg4, &msg);
+	LONGS_EQUAL(0, result);
+	msg_equal_32(0x84000061, 0, 0, 0, 0, 0, 0, 0);
+}
+
 TEST(ffa_api, ffa_msg_send_direct_resp_32_unknown_response)
 {
 	const uint16_t source_id = 0x1122;
diff --git a/components/messaging/ffa/libsp/test/test_ffa_memory_descriptors.cpp b/components/messaging/ffa/libsp/test/test_ffa_memory_descriptors.cpp
index 936625f..cfaf353 100644
--- a/components/messaging/ffa/libsp/test/test_ffa_memory_descriptors.cpp
+++ b/components/messaging/ffa/libsp/test/test_ffa_memory_descriptors.cpp
@@ -39,9 +39,31 @@
 		return *(Type *)&tx_buffer_area[offset];
 	}
 
-	template <typename Type> Type get_rx_value(uintptr_t offset)
+	void validate_mem_transaction_descriptor(uint16_t sender_id, uint16_t mem_region_attr, uint32_t flags, uint64_t handle, uint64_t tag, uint32_t mem_desc_count)
 	{
-		return *(Type *)&rx_buffer_area[offset];
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
+		UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
+		BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
+		BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
+		UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
+		UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
+		UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
+		UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
+		UNSIGNED_LONGS_EQUAL(mem_desc_count, get_tx_value<uint32_t>(28));
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+		uint8_t reserved[12] = { 0 };
+
+		UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
+		UNSIGNED_LONGS_EQUAL(mem_region_attr, get_tx_value<uint16_t>(2));
+		UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
+		UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
+		UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
+		UNSIGNED_LONGS_EQUAL(sizeof(struct ffa_mem_access_desc), get_tx_value<uint32_t>(24));
+		UNSIGNED_LONGS_EQUAL(mem_desc_count, get_tx_value<uint32_t>(28));
+		UNSIGNED_LONGS_EQUAL(sizeof(struct ffa_mem_transaction_desc),
+				     get_tx_value<uint32_t>(32));
+		MEMCMP_EQUAL(reserved, tx_buffer_area + 36, sizeof(reserved));
+#endif /* CFG_FFA_VERSION */
 	}
 
 	struct ffa_mem_transaction_buffer tx_buffer;
@@ -74,25 +96,15 @@
 	ffa_init_mem_transaction_desc(&tx_buffer, sender_id, mem_region_attr,
 				      flags, handle, tag);
 
-	UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
-	BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
-	BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
-	UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
-	UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
-	UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
-	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
-	UNSIGNED_LONGS_EQUAL(
-		0, get_tx_value<uint32_t>(28)); // Endpoint descriptor count
-
-	UNSIGNED_LONGS_EQUAL(sizeof(struct ffa_mem_transaction_desc),
-			     tx_buffer.used);
+	validate_mem_transaction_descriptor(sender_id, mem_region_attr, flags, handle, tag, 0);
+	UNSIGNED_LONGS_EQUAL(sizeof(struct ffa_mem_transaction_desc), tx_buffer.used);
 }
 
 TEST(ffa_memory_descriptors, ffa_init_mem_transaction_desc_buffer_overflow)
 {
 	assert_environment_t assert_env;
 
-	tx_buffer.length = 1;
+	tx_buffer.length = sizeof(struct ffa_mem_transaction_desc) - 1;
 
 	if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
 		ffa_init_mem_transaction_desc(&tx_buffer, sender_id,
@@ -112,6 +124,7 @@
 
 	transaction = ffa_get_mem_transaction_desc(&tx_buffer);
 
+#if CFG_FFA_VERSION == FFA_VERSION_1_0
 	UNSIGNED_LONGS_EQUAL(sender_id, transaction->sender_id);
 	BYTES_EQUAL(mem_region_attr, transaction->mem_region_attr);
 	BYTES_EQUAL(0, transaction->reserved_mbz0);
@@ -120,6 +133,18 @@
 	UNSIGNED_LONGLONGS_EQUAL(tag, transaction->tag);
 	UNSIGNED_LONGS_EQUAL(0, transaction->reserved_mbz1);
 	UNSIGNED_LONGS_EQUAL(0, transaction->mem_access_desc_count);
+#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
+	uint8_t reserved[12] = { 0 };
+
+	UNSIGNED_LONGS_EQUAL(sender_id, transaction->sender_id);
+	UNSIGNED_LONGS_EQUAL(mem_region_attr, transaction->mem_region_attr);
+	UNSIGNED_LONGS_EQUAL(flags, transaction->flags);
+	UNSIGNED_LONGLONGS_EQUAL(handle, transaction->handle);
+	UNSIGNED_LONGLONGS_EQUAL(tag, transaction->tag);
+	UNSIGNED_LONGS_EQUAL(sizeof(ffa_mem_access_desc), transaction->mem_access_desc_size);
+	UNSIGNED_LONGS_EQUAL(0, transaction->mem_access_desc_count);
+	MEMCMP_EQUAL(reserved, transaction->reserved_mbz0, sizeof(reserved));
+#endif /* CFG_FFA_VERSION */
 }
 
 TEST(ffa_memory_descriptors, ffa_reserve_mem_access_desc)
@@ -129,19 +154,10 @@
 
 	ffa_reserve_mem_access_desc(&tx_buffer, 3);
 
-	UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
-	BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
-	BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
-	UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
-	UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
-	UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
-	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
+	validate_mem_transaction_descriptor(sender_id, mem_region_attr, flags, handle, tag, 0);
 	UNSIGNED_LONGS_EQUAL(
-		0, get_tx_value<uint32_t>(28)); // Endpoint descriptor count
-
-	UNSIGNED_LONGS_EQUAL(sizeof(struct ffa_mem_transaction_desc) +
-				     sizeof(struct ffa_mem_access_desc) * 3,
-			     tx_buffer.used);
+		sizeof(struct ffa_mem_transaction_desc) + sizeof(struct ffa_mem_access_desc) * 3,
+		tx_buffer.used);
 }
 
 TEST(ffa_memory_descriptors, ffa_reserve_mem_access_desc_shrink)
@@ -152,20 +168,11 @@
 	ffa_reserve_mem_access_desc(&tx_buffer, 3);
 	ffa_reserve_mem_access_desc(&tx_buffer, 1);
 
-	UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
-	BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
-	BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
-	UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
-	UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
-	UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
-	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
-	UNSIGNED_LONGS_EQUAL(
-		0, get_tx_value<uint32_t>(28)); // Endpoint descriptor count
-
+	validate_mem_transaction_descriptor(sender_id, mem_region_attr, flags, handle, tag, 0);
 	/* It should not shrink the size */
-	UNSIGNED_LONGS_EQUAL(sizeof(struct ffa_mem_transaction_desc) +
-				     sizeof(struct ffa_mem_access_desc) * 3,
-			     tx_buffer.used);
+	UNSIGNED_LONGS_EQUAL(
+		sizeof(struct ffa_mem_transaction_desc) + sizeof(struct ffa_mem_access_desc) * 3,
+		tx_buffer.used);
 }
 
 TEST(ffa_memory_descriptors, ffa_reserve_mem_access_desc_buffer_overflow)
@@ -193,29 +200,18 @@
 
 	UNSIGNED_LONGS_EQUAL(0, desc_id);
 
-	UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
-	BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
-	BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
-	UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
-	UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
-	UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
-	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
-	UNSIGNED_LONGS_EQUAL(
-		1, get_tx_value<uint32_t>(28)); // Endpoint descriptor count
+	validate_mem_transaction_descriptor(sender_id, mem_region_attr, flags, handle, tag, 1);
 
 	uint32_t offset = sizeof(struct ffa_mem_transaction_desc);
-
 	UNSIGNED_LONGS_EQUAL(receiver_id, get_tx_value<uint16_t>(offset));
 	BYTES_EQUAL(mem_access_perm, get_tx_value<uint8_t>(offset + 2));
 	BYTES_EQUAL(flags2, get_tx_value<uint8_t>(offset + 3));
-	UNSIGNED_LONGS_EQUAL(
-		0, get_tx_value<uint16_t>(offset + 4)); // Composite offset
-	UNSIGNED_LONGLONGS_EQUAL(
-		0, get_tx_value<uint64_t>(offset + 8)); // Reserved
+	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint16_t>(offset + 4)); // Composite offset
+	UNSIGNED_LONGLONGS_EQUAL(0, get_tx_value<uint64_t>(offset + 8)); // Reserved
 
-	UNSIGNED_LONGS_EQUAL(sizeof(struct ffa_mem_transaction_desc) +
-				     sizeof(struct ffa_mem_access_desc),
-			     tx_buffer.used);
+	UNSIGNED_LONGS_EQUAL(
+		sizeof(struct ffa_mem_transaction_desc) + sizeof(struct ffa_mem_access_desc),
+		tx_buffer.used);
 }
 
 TEST(ffa_memory_descriptors, ffa_add_mem_access_desc_two)
@@ -231,18 +227,9 @@
 	UNSIGNED_LONGS_EQUAL(0, desc_id);
 	UNSIGNED_LONGS_EQUAL(1, desc_id2);
 
-	UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
-	BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
-	BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
-	UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
-	UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
-	UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
-	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
-	UNSIGNED_LONGS_EQUAL(
-		2, get_tx_value<uint32_t>(28)); // Endpoint descriptor count
+	validate_mem_transaction_descriptor(sender_id, mem_region_attr, flags, handle, tag, 2);
 
 	uint32_t offset = sizeof(struct ffa_mem_transaction_desc);
-
 	UNSIGNED_LONGS_EQUAL(receiver_id, get_tx_value<uint16_t>(offset));
 	BYTES_EQUAL(mem_access_perm, get_tx_value<uint8_t>(offset + 2));
 	BYTES_EQUAL(flags2, get_tx_value<uint8_t>(offset + 3));
@@ -264,9 +251,9 @@
 	UNSIGNED_LONGLONGS_EQUAL(
 		0, get_tx_value<uint64_t>(offset + 8)); // Reserved
 
-	UNSIGNED_LONGS_EQUAL(sizeof(struct ffa_mem_transaction_desc) +
-				     sizeof(struct ffa_mem_access_desc) * 2,
-			     tx_buffer.used);
+	UNSIGNED_LONGS_EQUAL(
+		sizeof(struct ffa_mem_transaction_desc) + sizeof(struct ffa_mem_access_desc) * 2,
+		tx_buffer.used);
 }
 
 TEST(ffa_memory_descriptors, ffa_add_mem_access_desc_buffer_overflow)
@@ -294,8 +281,7 @@
 	ffa_init_mem_transaction_desc(&tx_buffer, sender_id, mem_region_attr,
 				      flags, handle, tag);
 
-	((struct ffa_mem_transaction_desc *)tx_buffer_area)
-		->mem_access_desc_count = UINT32_MAX;
+	((struct ffa_mem_transaction_desc *)tx_buffer_area)->mem_access_desc_count = UINT32_MAX;
 
 	if (SETUP_ASSERT_ENVIRONMENT(assert_env)) {
 		ffa_add_mem_access_desc(&tx_buffer, receiver_id,
@@ -318,18 +304,9 @@
 	UNSIGNED_LONGS_EQUAL(0, desc_id);
 	UNSIGNED_LONGS_EQUAL(1, desc_id2);
 
-	UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
-	BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
-	BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
-	UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
-	UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
-	UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
-	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
-	UNSIGNED_LONGS_EQUAL(
-		2, get_tx_value<uint32_t>(28)); // Endpoint descriptor count
+	validate_mem_transaction_descriptor(sender_id, mem_region_attr, flags, handle, tag, 2);
 
 	uint32_t offset = sizeof(struct ffa_mem_transaction_desc);
-
 	UNSIGNED_LONGS_EQUAL(receiver_id, get_tx_value<uint16_t>(offset));
 	BYTES_EQUAL(mem_access_perm, get_tx_value<uint8_t>(offset + 2));
 	BYTES_EQUAL(flags2, get_tx_value<uint8_t>(offset + 3));
@@ -340,7 +317,6 @@
 
 	offset = sizeof(struct ffa_mem_transaction_desc) +
 		 sizeof(struct ffa_mem_access_desc);
-
 	UNSIGNED_LONGS_EQUAL((uint16_t)~receiver_id,
 			     get_tx_value<uint16_t>(offset));
 	BYTES_EQUAL((uint8_t)~mem_access_perm,
@@ -413,15 +389,7 @@
 
 	ffa_add_memory_region(&tx_buffer, ptr, 3);
 
-	UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
-	BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
-	BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
-	UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
-	UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
-	UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
-	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
-	UNSIGNED_LONGS_EQUAL(
-		1, get_tx_value<uint32_t>(28)); // Endpoint descriptor count
+	validate_mem_transaction_descriptor(sender_id, mem_region_attr, flags, handle, tag, 1);
 
 	uint32_t offset = sizeof(struct ffa_mem_transaction_desc);
 	uint32_t composite_offset = offset + sizeof(struct ffa_mem_access_desc);
@@ -461,15 +429,7 @@
 	ffa_add_memory_region(&tx_buffer, ptr, 3);
 	ffa_add_memory_region(&tx_buffer, ptr + 1, 2);
 
-	UNSIGNED_LONGS_EQUAL(sender_id, get_tx_value<uint16_t>(0));
-	BYTES_EQUAL(mem_region_attr, get_tx_value<uint8_t>(2));
-	BYTES_EQUAL(0, get_tx_value<uint8_t>(3));
-	UNSIGNED_LONGS_EQUAL(flags, get_tx_value<uint32_t>(4));
-	UNSIGNED_LONGLONGS_EQUAL(handle, get_tx_value<uint64_t>(8));
-	UNSIGNED_LONGLONGS_EQUAL(tag, get_tx_value<uint64_t>(16));
-	UNSIGNED_LONGS_EQUAL(0, get_tx_value<uint32_t>(24));
-	UNSIGNED_LONGS_EQUAL(
-		1, get_tx_value<uint32_t>(28)); // Endpoint descriptor count
+	validate_mem_transaction_descriptor(sender_id, mem_region_attr, flags, handle, tag, 1);
 
 	uint32_t offset = sizeof(struct ffa_mem_transaction_desc);
 	uint32_t composite_offset = offset + sizeof(struct ffa_mem_access_desc);
diff --git a/components/messaging/ffa/libsp/test/test_sp_discovery.cpp b/components/messaging/ffa/libsp/test/test_sp_discovery.cpp
index 5c48fe8..f19786f 100644
--- a/components/messaging/ffa/libsp/test/test_sp_discovery.cpp
+++ b/components/messaging/ffa/libsp/test/test_sp_discovery.cpp
@@ -225,6 +225,24 @@
 	MEMCMP_EQUAL(&expected_info, &info, sizeof(info));
 }
 
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+TEST(sp_discovery, sp_discovery_partition_info_invalid_desc_size)
+{
+	struct sp_uuid uuid = { 1 };
+	struct ffa_uuid ffa_uuid = { 1 };
+	uint32_t count = 1;
+	uint32_t size = 0;
+	struct sp_partition_info info = { 1 };
+	const struct sp_partition_info expected_info = { 0 };
+
+	expect_sp_rxtx_buffer_rx_get(&rx_buffer, &rx_buffer_size, SP_RESULT_OK);
+	expect_ffa_partition_info_get(&ffa_uuid, 0, &count, &size, FFA_OK);
+	LONGS_EQUAL(SP_RESULT_INTERNAL_ERROR,
+		    sp_discovery_partition_info_get(&uuid, &info, &count));
+	MEMCMP_EQUAL(&expected_info, &info, sizeof(info));
+}
+#endif
+
 TEST(sp_discovery, sp_discovery_partition_info_small_buffer)
 {
 	struct sp_uuid uuid = { 1 };
@@ -520,3 +538,65 @@
 	CHECK_FALSE(info[1].can_send_direct_requests);
 	CHECK_FALSE(info[1].supports_indirect_requests);
 }
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+TEST(sp_discovery, sp_discovery_partition_info_get_count_null)
+{
+	struct sp_uuid uuid = { 1 };
+
+	LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS,
+		    sp_discovery_partition_info_get_count(&uuid, NULL));
+}
+
+TEST(sp_discovery, sp_discovery_partition_info_get_count_uuid_null)
+{
+	uint32_t count = 1;
+
+	LONGS_EQUAL(SP_RESULT_INVALID_PARAMETERS,
+		    sp_discovery_partition_info_get_count(NULL, &count));
+	UNSIGNED_LONGS_EQUAL(0, count);
+}
+
+TEST(sp_discovery, sp_discovery_partition_info_get_count_ffa_error)
+{
+	struct ffa_uuid ffa_uuid = { 1 };
+	struct sp_uuid sp_uuid = { 1 };
+	const uint32_t expected_count = 1;
+	const uint32_t expected_size = 0;
+	uint32_t count = 0;
+
+	expect_ffa_partition_info_get(&ffa_uuid, 0x01, &expected_count, &expected_size,
+					   result);
+	LONGS_EQUAL(result,
+		    sp_discovery_partition_info_get_count(&sp_uuid, &count));
+}
+
+TEST(sp_discovery, sp_discovery_partition_info_get_count_invalid_size)
+{
+	struct ffa_uuid ffa_uuid = { 1 };
+	struct sp_uuid sp_uuid = { 1 };
+	const uint32_t expected_count = 1;
+	const uint32_t expected_size = 11;
+	uint32_t count = 0;
+
+	expect_ffa_partition_info_get(&ffa_uuid, 0x01, &expected_count, &expected_size,
+					   FFA_OK);
+	LONGS_EQUAL(SP_RESULT_INTERNAL_ERROR,
+		    sp_discovery_partition_info_get_count(&sp_uuid, &count));
+}
+
+TEST(sp_discovery, sp_discovery_partition_info_get_count)
+{
+	struct ffa_uuid ffa_uuid = { 1 };
+	struct sp_uuid sp_uuid = { 1 };
+	const uint32_t expected_count = 1;
+	const uint32_t expected_size = 0;
+	uint32_t count = 0;
+
+	expect_ffa_partition_info_get(&ffa_uuid, 0x01, &expected_count, &expected_size,
+					   FFA_OK);
+	LONGS_EQUAL(SP_RESULT_OK,
+		    sp_discovery_partition_info_get_count(&sp_uuid, &count));
+	UNSIGNED_LONGS_EQUAL(expected_count, count);
+}
+#endif /* CFG_FFA_VERSION */
diff --git a/components/messaging/ffa/libsp/tests.cmake b/components/messaging/ffa/libsp/tests.cmake
index eb0b41e..80df5cd 100644
--- a/components/messaging/ffa/libsp/tests.cmake
+++ b/components/messaging/ffa/libsp/tests.cmake
@@ -47,6 +47,25 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
+)
+
+unit_test_add_suite(
+	NAME libsp_ffa_v1_1
+	SOURCES
+		${CMAKE_CURRENT_LIST_DIR}/test/test_ffa_api.cpp
+		${CMAKE_CURRENT_LIST_DIR}/test/test_ffa_memory_descriptors.cpp
+		${CMAKE_CURRENT_LIST_DIR}/mock/mock_ffa_internal_api.cpp
+		${CMAKE_CURRENT_LIST_DIR}/ffa.c
+		${CMAKE_CURRENT_LIST_DIR}/ffa_memory_descriptors.c
+		${CMAKE_CURRENT_LIST_DIR}/mock/mock_assert.cpp
+	INCLUDE_DIRECTORIES
+		${CMAKE_CURRENT_LIST_DIR}/include/
+		${CMAKE_CURRENT_LIST_DIR}/mock
+		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
+	COMPILE_DEFINITIONS
+		-DARM64
+		-DCFG_FFA_VERSION=0x00010001
 )
 
 unit_test_add_suite(
@@ -60,6 +79,22 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
+)
+
+
+unit_test_add_suite(
+	NAME libsp_mock_ffa_api_v1_1
+	SOURCES
+		${CMAKE_CURRENT_LIST_DIR}/mock/test/test_mock_ffa_api.cpp
+		${CMAKE_CURRENT_LIST_DIR}/mock/mock_ffa_api.cpp
+	INCLUDE_DIRECTORIES
+		${CMAKE_CURRENT_LIST_DIR}/include/
+		${CMAKE_CURRENT_LIST_DIR}/mock
+		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
+	COMPILE_DEFINITIONS
+		-DARM64
+		-DCFG_FFA_VERSION=0x00010001
 )
 
 unit_test_add_suite(
@@ -74,6 +109,7 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -87,6 +123,7 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -102,6 +139,7 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -115,6 +153,7 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -132,6 +171,7 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -145,6 +185,7 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -160,6 +201,7 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -174,6 +216,7 @@
 		${UNIT_TEST_PROJECT_PATH}/components/common/utils/include
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -188,6 +231,7 @@
 	COMPILE_DEFINITIONS
 		-DARM64
 		-DFFA_DIRECT_MSG_ROUTING_EXTENSION=1
+		-DCFG_FFA_VERSION=0x00010000
 )
 
 unit_test_add_suite(
@@ -204,4 +248,5 @@
 	COMPILE_DEFINITIONS
 		-DARM64
 		-DFFA_DIRECT_MSG_ROUTING_EXTENSION=1
+		-DCFG_FFA_VERSION=0x00010000
 )
\ No newline at end of file
diff --git a/components/messaging/rss_comms/sp/component.cmake b/components/messaging/rse_comms/sp/component.cmake
similarity index 80%
rename from components/messaging/rss_comms/sp/component.cmake
rename to components/messaging/rse_comms/sp/component.cmake
index b9b7c4f..79b6a69 100644
--- a/components/messaging/rss_comms/sp/component.cmake
+++ b/components/messaging/rse_comms/sp/component.cmake
@@ -9,12 +9,12 @@
 endif()
 
 set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
-	"${CMAKE_CURRENT_LIST_DIR}/rss_comms_messenger_api.h"
+	"${CMAKE_CURRENT_LIST_DIR}/rse_comms_messenger_api.h"
 	)
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/rss_comms_messenger.c"
-	"${CMAKE_CURRENT_LIST_DIR}/rss_comms_platform.c"
+	"${CMAKE_CURRENT_LIST_DIR}/rse_comms_messenger.c"
+	"${CMAKE_CURRENT_LIST_DIR}/rse_comms_platform.c"
 	)
 
 target_include_directories(${TGT}
diff --git a/components/messaging/rse_comms/sp/rse_comms_messenger.c b/components/messaging/rse_comms/sp/rse_comms_messenger.c
new file mode 100644
index 0000000..48988f1
--- /dev/null
+++ b/components/messaging/rse_comms/sp/rse_comms_messenger.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <trace.h>
+
+#include "protocols/rpc/common/packed-c/status.h"
+#include "rse_comms_messenger_api.h"
+#include "rse_comms_platform_api.h"
+
+struct rse_comms_msg {
+	uint8_t *req_buf;
+	size_t req_len;
+	uint8_t *resp_buf;
+};
+
+int rse_comms_messenger_init(struct rse_comms_messenger *rse_comms)
+{
+	int ret = 0;
+
+	if (!rse_comms || rse_comms->msg || rse_comms->platform)
+		return -1;
+
+	rse_comms->msg = calloc(1, sizeof(struct rse_comms_msg));
+	if (!rse_comms->msg)
+		return -1;
+
+	rse_comms->platform = rse_comms_platform_init();
+	if (!rse_comms->platform) {
+		EMSG("Platform init failed");
+		free(rse_comms->msg);
+		rse_comms->msg = NULL;
+		return ret;
+	}
+
+	return 0;
+}
+
+void rse_comms_messenger_deinit(struct rse_comms_messenger *rse_comms)
+{
+	struct rse_comms_msg *msg = NULL;
+
+	if (!rse_comms)
+		return;
+
+	if (rse_comms->msg) {
+		msg = (struct rse_comms_msg *)rse_comms->msg;
+
+		if (msg->req_buf)
+			free(msg->req_buf);
+		if (msg->resp_buf)
+			free(msg->resp_buf);
+
+		free(msg);
+		rse_comms->msg = NULL;
+	}
+
+	rse_comms_platform_deinit(rse_comms->platform);
+	rse_comms->platform = NULL;
+}
+
+int rse_comms_messenger_call_invoke(struct rse_comms_messenger *rse_comms, uint8_t **resp_buf,
+				    size_t *resp_len)
+{
+	struct rse_comms_msg *msg = NULL;
+	int ret = 0;
+
+	if (!rse_comms || !resp_buf || !resp_len) {
+		EMSG("Invalid arguments");
+		return -1;
+	}
+
+	if (!rse_comms->msg) {
+		EMSG("msg is null");
+		return -1;
+	}
+
+	msg = (struct rse_comms_msg *)rse_comms->msg;
+	*resp_buf = calloc(1, *resp_len);
+
+	if (!(*resp_buf))
+		return -1;
+
+	ret = rse_comms_platform_invoke(rse_comms->platform, *resp_buf, msg->req_buf, resp_len,
+					msg->req_len);
+
+	if (ret < 0) {
+		free(*resp_buf);
+		*resp_buf = NULL;
+		return ret;
+	}
+
+	msg->resp_buf = *resp_buf;
+
+	return 0;
+}
+
+int rse_comms_messenger_call_begin(struct rse_comms_messenger *rse_comms, uint8_t **req_buf,
+				   size_t req_len)
+{
+	int ret = 0;
+	struct rse_comms_msg *msg = NULL;
+
+	if (!rse_comms || !req_buf || !rse_comms->msg)
+		return -1;
+
+	if (req_len > UINT32_MAX || req_len == 0) {
+		EMSG("req_len invalid: %lu", req_len);
+		return -1;
+	}
+
+	msg = (struct rse_comms_msg *)rse_comms->msg;
+
+	if (msg->req_buf)
+		return -1;
+
+	msg->req_buf = calloc(1, req_len);
+
+	if (!msg->req_buf)
+		return -1;
+
+	*req_buf = msg->req_buf;
+	msg->req_len = req_len;
+
+	ret = rse_comms_platform_begin(rse_comms->platform, *req_buf, req_len);
+
+	return ret;
+}
+
+void rse_comms_messenger_call_end(struct rse_comms_messenger *rse_comms)
+{
+	int ret = 0;
+	struct rse_comms_msg *msg = NULL;
+
+	if (!rse_comms || !rse_comms->msg)
+		return;
+
+	msg = (struct rse_comms_msg *)rse_comms->msg;
+
+	if (msg->req_buf)
+		free(msg->req_buf);
+
+	if (msg->resp_buf)
+		free(msg->resp_buf);
+
+	msg->req_len = 0;
+	msg->req_buf = NULL;
+	msg->resp_buf = NULL;
+
+	ret = rse_comms_platform_end(rse_comms->platform);
+
+	if (ret < 0) {
+		EMSG("Platform end failed: %d", ret);
+		return;
+	}
+}
diff --git a/components/messaging/rse_comms/sp/rse_comms_messenger_api.h b/components/messaging/rse_comms/sp/rse_comms_messenger_api.h
new file mode 100644
index 0000000..fcf9c95
--- /dev/null
+++ b/components/messaging/rse_comms/sp/rse_comms_messenger_api.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __RSE_COMMS_MESSENGER_API_H__
+#define __RSE_COMMS_MESSENGER_API_H__
+
+#include <stddef.h>
+#include <stdint.h>
+
+struct rse_comms_messenger {
+	void *msg;
+	void *platform;
+};
+
+int rse_comms_messenger_init(struct rse_comms_messenger *rse_comms);
+void rse_comms_messenger_deinit(struct rse_comms_messenger *rse_comms);
+int rse_comms_messenger_call_invoke(struct rse_comms_messenger *rse_comms, uint8_t **resp_buf,
+				    size_t *resp_len);
+int rse_comms_messenger_call_begin(struct rse_comms_messenger *rse_comms, uint8_t **req_buf,
+				   size_t req_len);
+void rse_comms_messenger_call_end(struct rse_comms_messenger *rse_comms);
+
+#endif /* __RSE_COMMS_MESSENGER_API_H__ */
diff --git a/components/messaging/rse_comms/sp/rse_comms_platform.c b/components/messaging/rse_comms/sp/rse_comms_platform.c
new file mode 100644
index 0000000..f8f6edb
--- /dev/null
+++ b/components/messaging/rse_comms/sp/rse_comms_platform.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <trace.h>
+
+#include "platform/interface/mhu_interface.h"
+#include "rse_comms_messenger_api.h"
+#include "rse_comms_platform_api.h"
+
+struct rse_comms_platform {
+	struct platform_mhu_driver rx_dev;
+	struct platform_mhu_driver tx_dev;
+};
+
+struct rse_comms_platform *rse_comms_platform_init(void)
+{
+	struct rse_comms_platform *rse_comms_plat = NULL;
+	int ret = 0;
+
+	rse_comms_plat = calloc(1, sizeof(*rse_comms_plat));
+	if (!rse_comms_plat) {
+		EMSG("rse_comms calloc dev failed");
+		return NULL;
+	}
+
+	ret = platform_mhu_create(&rse_comms_plat->rx_dev, "mhu-receiver", true);
+	if (ret < 0)
+		goto free_plat;
+
+	ret = platform_mhu_create(&rse_comms_plat->tx_dev, "mhu-sender", false);
+	if (ret < 0)
+		goto free_rx_dev;
+
+	return rse_comms_plat;
+
+free_rx_dev:
+	platform_mhu_destroy(&rse_comms_plat->rx_dev);
+free_plat:
+	free(rse_comms_plat);
+
+	return NULL;
+}
+
+int rse_comms_platform_deinit(struct rse_comms_platform *rse_comms_plat)
+{
+	if (!rse_comms_plat)
+		return -1;
+
+	platform_mhu_destroy(&rse_comms_plat->rx_dev);
+	platform_mhu_destroy(&rse_comms_plat->tx_dev);
+
+	free(rse_comms_plat);
+
+	return 0;
+}
+
+int rse_comms_platform_invoke(struct rse_comms_platform *rse_comms_plat, uint8_t *resp_buf,
+			      uint8_t *req_buf, size_t *resp_len, size_t req_len)
+{
+	struct platform_mhu_driver *rx_dev = NULL;
+	struct platform_mhu_driver *tx_dev = NULL;
+	int err = 0;
+
+	if (!rse_comms_plat || !resp_buf || !req_buf)
+		return -1;
+
+	rx_dev = &rse_comms_plat->rx_dev;
+	tx_dev = &rse_comms_plat->tx_dev;
+
+	if (!tx_dev->iface || !tx_dev->iface->send)
+		return -1;
+
+	err = tx_dev->iface->send(tx_dev->context, req_buf, req_len);
+	if (err != 0) {
+		EMSG("mhu send data failed!");
+		return -1;
+	}
+
+	if (!rx_dev->iface || !rx_dev->iface->wait_data || !rx_dev->iface->receive)
+		return -1;
+
+	err = rx_dev->iface->wait_data(rx_dev->context);
+	if (err != 0) {
+		EMSG("mhu wait for signal failed!");
+		return -1;
+	}
+
+	err = rx_dev->iface->receive(rx_dev->context, resp_buf, resp_len);
+	if (err != 0) {
+		EMSG("mhu receive data failed!");
+		return -1;
+	}
+
+	return 0;
+}
+
+int rse_comms_platform_begin(struct rse_comms_platform *rse_comms_plat, uint8_t *req_buf,
+			     size_t req_len)
+{
+	return 0;
+}
+
+int rse_comms_platform_end(struct rse_comms_platform *rse_comms_plat)
+{
+	return 0;
+}
diff --git a/components/messaging/rse_comms/sp/rse_comms_platform_api.h b/components/messaging/rse_comms/sp/rse_comms_platform_api.h
new file mode 100644
index 0000000..5b58fa2
--- /dev/null
+++ b/components/messaging/rse_comms/sp/rse_comms_platform_api.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __RSE_COMMS_PLATFORM_API_H__
+#define __RSE_COMMS_PLATFORM_API_H__
+
+#include <stdint.h>
+
+struct rse_comms_platform;
+
+struct rse_comms_platform *rse_comms_platform_init(void);
+int rse_comms_platform_deinit(struct rse_comms_platform *rse_comms_plat);
+int rse_comms_platform_invoke(struct rse_comms_platform *rse_comms_plat, uint8_t *resp_buf,
+			      uint8_t *req_buf, size_t *resp_len, size_t req_len);
+int rse_comms_platform_begin(struct rse_comms_platform *rse_comms_plat, uint8_t *req_buf,
+			     size_t req_len);
+int rse_comms_platform_end(struct rse_comms_platform *rse_comms_plat);
+
+#endif /* __RSE_COMMS_PLATFORM_API_H__ */
diff --git a/components/messaging/rss_comms/sp/rss_comms_messenger.c b/components/messaging/rss_comms/sp/rss_comms_messenger.c
deleted file mode 100644
index 644181e..0000000
--- a/components/messaging/rss_comms/sp/rss_comms_messenger.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <errno.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <trace.h>
-
-#include "protocols/rpc/common/packed-c/status.h"
-#include "rss_comms_messenger_api.h"
-#include "rss_comms_platform_api.h"
-
-struct rss_comms_msg {
-	uint8_t *req_buf;
-	size_t req_len;
-	uint8_t *resp_buf;
-};
-
-int rss_comms_messenger_init(struct rss_comms_messenger *rss_comms)
-{
-	int ret = 0;
-
-	if (!rss_comms || rss_comms->msg || rss_comms->platform)
-		return -1;
-
-	rss_comms->msg = calloc(1, sizeof(struct rss_comms_msg));
-	if (!rss_comms->msg)
-		return -1;
-
-	rss_comms->platform = rss_comms_platform_init();
-	if (!rss_comms->platform) {
-		EMSG("Platform init failed");
-		free(rss_comms->msg);
-		rss_comms->msg = NULL;
-		return ret;
-	}
-
-	return 0;
-}
-
-void rss_comms_messenger_deinit(struct rss_comms_messenger *rss_comms)
-{
-	struct rss_comms_msg *msg = NULL;
-
-	if (!rss_comms)
-		return;
-
-	if (rss_comms->msg) {
-		msg = (struct rss_comms_msg *)rss_comms->msg;
-
-		if (msg->req_buf)
-			free(msg->req_buf);
-		if (msg->resp_buf)
-			free(msg->resp_buf);
-
-		free(msg);
-		rss_comms->msg = NULL;
-	}
-
-	rss_comms_platform_deinit(rss_comms->platform);
-	rss_comms->platform = NULL;
-}
-
-int rss_comms_messenger_call_invoke(struct rss_comms_messenger *rss_comms, uint8_t **resp_buf,
-				    size_t *resp_len)
-{
-	struct rss_comms_msg *msg = NULL;
-	int ret = 0;
-
-	if (!rss_comms || !resp_buf || !resp_len) {
-		EMSG("Invalid arguments");
-		return -1;
-	}
-
-	if (!rss_comms->msg) {
-		EMSG("msg is null");
-		return -1;
-	}
-
-	msg = (struct rss_comms_msg *)rss_comms->msg;
-	*resp_buf = calloc(1, *resp_len);
-
-	if (!(*resp_buf))
-		return -1;
-
-	ret = rss_comms_platform_invoke(rss_comms->platform, *resp_buf, msg->req_buf, resp_len,
-					msg->req_len);
-
-	if (ret < 0) {
-		free(*resp_buf);
-		*resp_buf = NULL;
-		return ret;
-	}
-
-	msg->resp_buf = *resp_buf;
-
-	return 0;
-}
-
-int rss_comms_messenger_call_begin(struct rss_comms_messenger *rss_comms, uint8_t **req_buf,
-				   size_t req_len)
-{
-	int ret = 0;
-	struct rss_comms_msg *msg = NULL;
-
-	if (!rss_comms || !req_buf || !rss_comms->msg)
-		return -1;
-
-	if (req_len > UINT32_MAX || req_len == 0) {
-		EMSG("req_len invalid: %lu", req_len);
-		return -1;
-	}
-
-	msg = (struct rss_comms_msg *)rss_comms->msg;
-
-	if (msg->req_buf)
-		return -1;
-
-	msg->req_buf = calloc(1, req_len);
-
-	if (!msg->req_buf)
-		return -1;
-
-	*req_buf = msg->req_buf;
-	msg->req_len = req_len;
-
-	ret = rss_comms_platform_begin(rss_comms->platform, *req_buf, req_len);
-
-	return ret;
-}
-
-void rss_comms_messenger_call_end(struct rss_comms_messenger *rss_comms)
-{
-	int ret = 0;
-	struct rss_comms_msg *msg = NULL;
-
-	if (!rss_comms || !rss_comms->msg)
-		return;
-
-	msg = (struct rss_comms_msg *)rss_comms->msg;
-
-	if (msg->req_buf)
-		free(msg->req_buf);
-
-	if (msg->resp_buf)
-		free(msg->resp_buf);
-
-	msg->req_len = 0;
-	msg->req_buf = NULL;
-	msg->resp_buf = NULL;
-
-	ret = rss_comms_platform_end(rss_comms->platform);
-
-	if (ret < 0) {
-		EMSG("Platform end failed: %d", ret);
-		return;
-	}
-}
diff --git a/components/messaging/rss_comms/sp/rss_comms_messenger_api.h b/components/messaging/rss_comms/sp/rss_comms_messenger_api.h
deleted file mode 100644
index 02bb6b5..0000000
--- a/components/messaging/rss_comms/sp/rss_comms_messenger_api.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __RSS_COMMS_MESSENGER_API_H__
-#define __RSS_COMMS_MESSENGER_API_H__
-
-#include <stddef.h>
-#include <stdint.h>
-
-struct rss_comms_messenger {
-	void *msg;
-	void *platform;
-};
-
-int rss_comms_messenger_init(struct rss_comms_messenger *rss_comms);
-void rss_comms_messenger_deinit(struct rss_comms_messenger *rss_comms);
-int rss_comms_messenger_call_invoke(struct rss_comms_messenger *rss_comms, uint8_t **resp_buf,
-				    size_t *resp_len);
-int rss_comms_messenger_call_begin(struct rss_comms_messenger *rss_comms, uint8_t **req_buf,
-				   size_t req_len);
-void rss_comms_messenger_call_end(struct rss_comms_messenger *rss_comms);
-
-#endif /* __RSS_COMMS_MESSENGER_API_H__ */
diff --git a/components/messaging/rss_comms/sp/rss_comms_platform.c b/components/messaging/rss_comms/sp/rss_comms_platform.c
deleted file mode 100644
index 5e09db2..0000000
--- a/components/messaging/rss_comms/sp/rss_comms_platform.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <trace.h>
-
-#include "platform/interface/mhu_interface.h"
-#include "rss_comms_messenger_api.h"
-#include "rss_comms_platform_api.h"
-
-struct rss_comms_platform {
-	struct platform_mhu_driver rx_dev;
-	struct platform_mhu_driver tx_dev;
-};
-
-struct rss_comms_platform *rss_comms_platform_init(void)
-{
-	struct rss_comms_platform *rss_comms_plat = NULL;
-	int ret = 0;
-
-	rss_comms_plat = calloc(1, sizeof(*rss_comms_plat));
-	if (!rss_comms_plat) {
-		EMSG("rss_comms calloc dev failed");
-		return NULL;
-	}
-
-	ret = platform_mhu_create(&rss_comms_plat->rx_dev, "mhu-receiver", true);
-	if (ret < 0)
-		goto free_plat;
-
-	ret = platform_mhu_create(&rss_comms_plat->tx_dev, "mhu-sender", false);
-	if (ret < 0)
-		goto free_rx_dev;
-
-	return rss_comms_plat;
-
-free_rx_dev:
-	platform_mhu_destroy(&rss_comms_plat->rx_dev);
-free_plat:
-	free(rss_comms_plat);
-
-	return NULL;
-}
-
-int rss_comms_platform_deinit(struct rss_comms_platform *rss_comms_plat)
-{
-	if (!rss_comms_plat)
-		return -1;
-
-	platform_mhu_destroy(&rss_comms_plat->rx_dev);
-	platform_mhu_destroy(&rss_comms_plat->tx_dev);
-
-	free(rss_comms_plat);
-
-	return 0;
-}
-
-int rss_comms_platform_invoke(struct rss_comms_platform *rss_comms_plat, uint8_t *resp_buf,
-			      uint8_t *req_buf, size_t *resp_len, size_t req_len)
-{
-	struct platform_mhu_driver *rx_dev = NULL;
-	struct platform_mhu_driver *tx_dev = NULL;
-	int err = 0;
-
-	if (!rss_comms_plat || !resp_buf || !req_buf)
-		return -1;
-
-	rx_dev = &rss_comms_plat->rx_dev;
-	tx_dev = &rss_comms_plat->tx_dev;
-
-	if (!tx_dev->iface || !tx_dev->iface->send)
-		return -1;
-
-	err = tx_dev->iface->send(tx_dev->context, req_buf, req_len);
-	if (err != 0) {
-		EMSG("mhu send data failed!");
-		return -1;
-	}
-
-	if (!rx_dev->iface || !rx_dev->iface->wait_data || !rx_dev->iface->receive)
-		return -1;
-
-	err = rx_dev->iface->wait_data(rx_dev->context);
-	if (err != 0) {
-		EMSG("mhu wait for signal failed!");
-		return -1;
-	}
-
-	err = rx_dev->iface->receive(rx_dev->context, resp_buf, resp_len);
-	if (err != 0) {
-		EMSG("mhu receive data failed!");
-		return -1;
-	}
-
-	return 0;
-}
-
-int rss_comms_platform_begin(struct rss_comms_platform *rss_comms_plat, uint8_t *req_buf,
-			     size_t req_len)
-{
-	return 0;
-}
-
-int rss_comms_platform_end(struct rss_comms_platform *rss_comms_plat)
-{
-	return 0;
-}
diff --git a/components/messaging/rss_comms/sp/rss_comms_platform_api.h b/components/messaging/rss_comms/sp/rss_comms_platform_api.h
deleted file mode 100644
index ed55506..0000000
--- a/components/messaging/rss_comms/sp/rss_comms_platform_api.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __RSS_COMMS_PLATFORM_API_H__
-#define __RSS_COMMS_PLATFORM_API_H__
-
-#include <stdint.h>
-
-struct rss_comms_platform;
-
-struct rss_comms_platform *rss_comms_platform_init(void);
-int rss_comms_platform_deinit(struct rss_comms_platform *rss_comms_plat);
-int rss_comms_platform_invoke(struct rss_comms_platform *rss_comms_plat, uint8_t *resp_buf,
-			      uint8_t *req_buf, size_t *resp_len, size_t req_len);
-int rss_comms_platform_begin(struct rss_comms_platform *rss_comms_plat, uint8_t *req_buf,
-			     size_t req_len);
-int rss_comms_platform_end(struct rss_comms_platform *rss_comms_plat);
-
-#endif /* __RSS_COMMS_PLATFORM_API_H__ */
diff --git a/components/rpc/mm_communicate/endpoint/sp/tests.cmake b/components/rpc/mm_communicate/endpoint/sp/tests.cmake
index c68a0c7..51e4d9c 100644
--- a/components/rpc/mm_communicate/endpoint/sp/tests.cmake
+++ b/components/rpc/mm_communicate/endpoint/sp/tests.cmake
@@ -22,4 +22,5 @@
 		${UNIT_TEST_PROJECT_PATH}/components/rpc/common/interface
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010001
 )
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_caller.c b/components/rpc/rse_comms/caller/sp/rse_comms_caller.c
similarity index 66%
rename from components/rpc/rss_comms/caller/sp/rss_comms_caller.c
rename to components/rpc/rse_comms/caller/sp/rse_comms_caller.c
index d857a2e..964b391 100644
--- a/components/rpc/rss_comms/caller/sp/rss_comms_caller.c
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_caller.c
@@ -4,7 +4,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include "rss_comms_caller.h"
+#include "rse_comms_caller.h"
 
 #include <stddef.h>
 #include <stdlib.h>
@@ -13,8 +13,8 @@
 #include "rpc_caller.h"
 #include "rpc_status.h"
 
-struct rss_comms_caller_context {
-	struct rss_comms_messenger rss_comms;
+struct rse_comms_caller_context {
+	struct rse_comms_messenger rse_comms;
 };
 
 rpc_status_t open_session(void *context, const struct rpc_uuid *service_uuid, uint16_t endpoint_id)
@@ -49,19 +49,19 @@
 	return RPC_ERROR_INTERNAL;
 }
 
-rpc_status_t rss_comms_caller_invoke(rss_comms_call_handle handle, uint32_t opcode,
+rpc_status_t rse_comms_caller_invoke(rse_comms_call_handle handle, uint32_t opcode,
 				     uint8_t **response_buffer, size_t *response_length)
 {
 	struct rpc_caller_interface *caller = (struct rpc_caller_interface *)handle;
-	struct rss_comms_caller_context *context = NULL;
+	struct rse_comms_caller_context *context = NULL;
 	int ret = 0;
 
 	if (!handle || !caller->context)
 		return RPC_ERROR_INVALID_VALUE;
 
-	context = (struct rss_comms_caller_context *)caller->context;
+	context = (struct rse_comms_caller_context *)caller->context;
 
-	ret = rss_comms_messenger_call_invoke(&context->rss_comms, response_buffer,
+	ret = rse_comms_messenger_call_invoke(&context->rse_comms, response_buffer,
 					      response_length);
 	if (ret < 0)
 		return RPC_ERROR_TRANSPORT_LAYER;
@@ -69,20 +69,20 @@
 	return RPC_SUCCESS;
 }
 
-rpc_status_t rss_comms_caller_init(struct rpc_caller_interface *rpc_caller)
+rpc_status_t rse_comms_caller_init(struct rpc_caller_interface *rpc_caller)
 {
-	struct rss_comms_caller_context *context = NULL;
+	struct rse_comms_caller_context *context = NULL;
 	int ret = 0;
 
 	if (!rpc_caller || rpc_caller->context)
 		return RPC_ERROR_INVALID_VALUE;
 
-	context = (struct rss_comms_caller_context *)calloc(1,
-				sizeof(struct rss_comms_caller_context));
+	context = (struct rse_comms_caller_context *)calloc(1,
+				sizeof(struct rse_comms_caller_context));
 	if (!context)
 		return RPC_ERROR_INTERNAL;
 
-	ret = rss_comms_messenger_init(&context->rss_comms);
+	ret = rse_comms_messenger_init(&context->rse_comms);
 
 	if (ret < 0) {
 		free(context);
@@ -100,18 +100,18 @@
 	return RPC_SUCCESS;
 }
 
-rss_comms_call_handle rss_comms_caller_begin(struct rpc_caller_interface *caller,
+rse_comms_call_handle rse_comms_caller_begin(struct rpc_caller_interface *caller,
 					     uint8_t **request_buffer, size_t request_length)
 {
-	struct rss_comms_caller_context *context = NULL;
+	struct rse_comms_caller_context *context = NULL;
 	int ret = 0;
 
 	if (!caller || !caller->context)
 		return NULL;
 
-	context = (struct rss_comms_caller_context *)caller->context;
+	context = (struct rse_comms_caller_context *)caller->context;
 
-	ret = rss_comms_messenger_call_begin(&context->rss_comms, request_buffer, request_length);
+	ret = rse_comms_messenger_call_begin(&context->rse_comms, request_buffer, request_length);
 
 	if (ret < 0)
 		return NULL;
@@ -119,31 +119,31 @@
 	return caller;
 }
 
-rpc_status_t rss_comms_caller_end(rss_comms_call_handle handle)
+rpc_status_t rse_comms_caller_end(rse_comms_call_handle handle)
 {
 	struct rpc_caller_interface *caller = (struct rpc_caller_interface *)handle;
-	struct rss_comms_caller_context *context = NULL;
+	struct rse_comms_caller_context *context = NULL;
 
 	if (!handle || !caller->context)
 		return RPC_ERROR_INVALID_VALUE;
 
-	context = (struct rss_comms_caller_context *)caller->context;
+	context = (struct rse_comms_caller_context *)caller->context;
 
-	rss_comms_messenger_call_end(&context->rss_comms);
+	rse_comms_messenger_call_end(&context->rse_comms);
 
 	return RPC_SUCCESS;
 }
 
-rpc_status_t rss_comms_caller_deinit(struct rpc_caller_interface *rpc_caller)
+rpc_status_t rse_comms_caller_deinit(struct rpc_caller_interface *rpc_caller)
 {
-	struct rss_comms_caller_context *context = NULL;
+	struct rse_comms_caller_context *context = NULL;
 
 	if (!rpc_caller)
 		return RPC_ERROR_INVALID_VALUE;
 
-	context = (struct rss_comms_caller_context *)rpc_caller->context;
+	context = (struct rse_comms_caller_context *)rpc_caller->context;
 
-	rss_comms_messenger_deinit(&context->rss_comms);
+	rse_comms_messenger_deinit(&context->rse_comms);
 
 	free(context);
 	rpc_caller->context = NULL;
diff --git a/components/rpc/rse_comms/caller/sp/rse_comms_caller.h b/components/rpc/rse_comms/caller/sp/rse_comms_caller.h
new file mode 100644
index 0000000..7c8c38e
--- /dev/null
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_caller.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef __RSE_COMMS_CALLER_H__
+#define __RSE_COMMS_CALLER_H__
+
+#include "rpc_caller.h"
+#include "rse_comms_messenger_api.h"
+
+typedef void *rse_comms_call_handle;
+
+rpc_status_t rse_comms_caller_init(struct rpc_caller_interface *rpc_caller);
+rpc_status_t rse_comms_caller_deinit(struct rpc_caller_interface *rpc_caller);
+
+rse_comms_call_handle rse_comms_caller_begin(struct rpc_caller_interface *caller,
+					     uint8_t **request_buffer, size_t request_length);
+
+rpc_status_t rse_comms_caller_invoke(rse_comms_call_handle handle, uint32_t opcode,
+				     uint8_t **response_buffer, size_t *response_length);
+
+rpc_status_t rse_comms_caller_end(rse_comms_call_handle handle);
+
+#endif /* __RSE_COMMS_CALLER_H__ */
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_protocol.c b/components/rpc/rse_comms/caller/sp/rse_comms_protocol.c
similarity index 62%
rename from components/rpc/rss_comms/caller/sp/rss_comms_protocol.c
rename to components/rpc/rse_comms/caller/sp/rse_comms_protocol.c
index 7969536..7c2f476 100644
--- a/components/rpc/rss_comms/caller/sp/rss_comms_protocol.c
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_protocol.c
@@ -6,15 +6,15 @@
  */
 #include <assert.h>
 
-#include "rss_comms_protocol.h"
+#include "rse_comms_protocol.h"
 
-psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_serialize_msg(psa_handle_t handle,
 					int16_t type,
 					const struct psa_invec *in_vec,
 					uint8_t in_len,
 					const struct psa_outvec *out_vec,
 					uint8_t out_len,
-					struct serialized_rss_comms_msg_t *msg,
+					struct serialized_rse_comms_msg_t *msg,
 					size_t *msg_len)
 {
 	psa_status_t status = PSA_SUCCESS;
@@ -24,15 +24,15 @@
 	assert(in_vec != NULL);
 
 	switch (msg->header.protocol_ver) {
-	case RSS_COMMS_PROTOCOL_EMBED:
-		status = rss_protocol_embed_serialize_msg(handle, type, in_vec, in_len, out_vec,
+	case RSE_COMMS_PROTOCOL_EMBED:
+		status = rse_protocol_embed_serialize_msg(handle, type, in_vec, in_len, out_vec,
 							  out_len, &msg->msg.embed, msg_len);
 		if (status != PSA_SUCCESS) {
 			return status;
 		}
 		break;
-	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
-		status = rss_protocol_pointer_access_serialize_msg(handle, type, in_vec, in_len,
+	case RSE_COMMS_PROTOCOL_POINTER_ACCESS:
+		status = rse_protocol_pointer_access_serialize_msg(handle, type, in_vec, in_len,
 								   out_vec, out_len,
 								   &msg->msg.pointer_access,
 								   msg_len);
@@ -44,26 +44,26 @@
 		return PSA_ERROR_NOT_SUPPORTED;
 	}
 
-	*msg_len += sizeof(struct serialized_rss_comms_header_t);
+	*msg_len += sizeof(struct serialized_rse_comms_header_t);
 
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_deserialize_reply(struct psa_outvec *out_vec,
+psa_status_t rse_protocol_deserialize_reply(struct psa_outvec *out_vec,
 					    uint8_t out_len,
 					    psa_status_t *return_val,
-					    const struct serialized_rss_comms_reply_t *reply,
+					    const struct serialized_rse_comms_reply_t *reply,
 					    size_t reply_size)
 {
 	assert(reply != NULL);
 	assert(return_val != NULL);
 
 	switch (reply->header.protocol_ver) {
-	case RSS_COMMS_PROTOCOL_EMBED:
-		return rss_protocol_embed_deserialize_reply(out_vec, out_len, return_val,
+	case RSE_COMMS_PROTOCOL_EMBED:
+		return rse_protocol_embed_deserialize_reply(out_vec, out_len, return_val,
 							    &reply->reply.embed, reply_size);
-	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
-		return rss_protocol_pointer_access_deserialize_reply(out_vec, out_len, return_val,
+	case RSE_COMMS_PROTOCOL_POINTER_ACCESS:
+		return rse_protocol_pointer_access_deserialize_reply(out_vec, out_len, return_val,
 								     &reply->reply.pointer_access,
 								     reply_size);
 	default:
@@ -73,7 +73,7 @@
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_calculate_msg_len(psa_handle_t handle,
+psa_status_t rse_protocol_calculate_msg_len(psa_handle_t handle,
 					    uint8_t protocol_ver,
 					    const struct psa_invec *in_vec,
 					    uint8_t in_len,
@@ -85,18 +85,18 @@
 	assert(in_vec != NULL);
 
 	switch (protocol_ver) {
-	case RSS_COMMS_PROTOCOL_EMBED:
-		status = rss_protocol_embed_calculate_msg_len(handle, in_vec, in_len, msg_len);
+	case RSE_COMMS_PROTOCOL_EMBED:
+		status = rse_protocol_embed_calculate_msg_len(handle, in_vec, in_len, msg_len);
 		if (status != PSA_SUCCESS)
 			return status;
 
 		break;
-	case RSS_COMMS_PROTOCOL_POINTER_ACCESS:
+	case RSE_COMMS_PROTOCOL_POINTER_ACCESS:
 	default:
 		return PSA_ERROR_NOT_SUPPORTED;
 	}
 
-	*msg_len += sizeof(struct serialized_rss_comms_header_t);
+	*msg_len += sizeof(struct serialized_rse_comms_header_t);
 
 	return PSA_SUCCESS;
 }
diff --git a/components/rpc/rse_comms/caller/sp/rse_comms_protocol.h b/components/rpc/rse_comms/caller/sp/rse_comms_protocol.h
new file mode 100644
index 0000000..5c0f8a9
--- /dev/null
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_protocol.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSE_COMMS_PROTOCOL_H__
+#define __RSE_COMMS_PROTOCOL_H__
+
+#include <stdint.h>
+
+#include <psa/client.h>
+#include "rse_comms_protocol_embed.h"
+#include "rse_comms_protocol_pointer_access.h"
+#include "service/common/include/psa/client.h"
+
+enum rse_comms_protocol_version_t {
+	RSE_COMMS_PROTOCOL_EMBED = 0,
+	RSE_COMMS_PROTOCOL_POINTER_ACCESS = 1,
+};
+
+struct __packed serialized_rse_comms_header_t {
+	uint8_t protocol_ver;
+	uint8_t seq_num;
+	uint16_t client_id;
+};
+
+/* MHU message passed from Host to RSE to deliver a PSA client call */
+struct __packed serialized_rse_comms_msg_t {
+	struct serialized_rse_comms_header_t header;
+	union __packed {
+		struct rse_embed_msg_t embed;
+		struct rse_pointer_access_msg_t pointer_access;
+	} msg;
+};
+
+/* MHU reply message to hold the PSA client reply result returned by RSE */
+struct __packed serialized_rse_comms_reply_t {
+	struct serialized_rse_comms_header_t header;
+	union __packed {
+		struct rse_embed_reply_t embed;
+		struct rse_pointer_access_reply_t pointer_access;
+	} reply;
+};
+
+psa_status_t rse_protocol_serialize_msg(psa_handle_t handle,
+					int16_t type,
+					const struct psa_invec *in_vec,
+					uint8_t in_len,
+					const struct psa_outvec *out_vec,
+					uint8_t out_len,
+					struct serialized_rse_comms_msg_t *msg,
+					size_t *msg_len);
+
+psa_status_t rse_protocol_deserialize_reply(struct psa_outvec *out_vec,
+					    uint8_t out_len,
+					    psa_status_t *return_val,
+					    const struct serialized_rse_comms_reply_t *reply,
+					    size_t reply_size);
+
+psa_status_t rse_protocol_calculate_msg_len(psa_handle_t handle,
+					    uint8_t protocol_ver,
+					    const struct psa_invec *in_vec,
+					    uint8_t in_len,
+					    size_t *msg_len);
+
+#endif /* __RSE_COMMS_PROTOCOL_H__ */
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_common.h b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_common.h
similarity index 89%
rename from components/rpc/rss_comms/caller/sp/rss_comms_protocol_common.h
rename to components/rpc/rse_comms/caller/sp/rse_comms_protocol_common.h
index 177d636..235ea92 100644
--- a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_common.h
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_common.h
@@ -17,8 +17,8 @@
  * Res: Reserved.
  */
 
-#ifndef RSS_COMMS_PROTOCOL_COMMON
-#define RSS_COMMS_PROTOCOL_COMMON
+#ifndef RSE_COMMS_PROTOCOL_COMMON
+#define RSE_COMMS_PROTOCOL_COMMON
 
 #define TYPE_OFFSET	(0U)
 #define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
@@ -32,4 +32,4 @@
 	 ((((uint32_t)(in_len)) << IN_LEN_OFFSET) & IN_LEN_MASK) | \
 	 ((((uint32_t)(out_len)) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
 
-#endif /* RSS_COMMS_PROTOCOL_COMMON */
+#endif /* RSE_COMMS_PROTOCOL_COMMON */
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_embed.c b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_embed.c
similarity index 83%
rename from components/rpc/rss_comms/caller/sp/rss_comms_protocol_embed.c
rename to components/rpc/rse_comms/caller/sp/rse_comms_protocol_embed.c
index 6d96ff2..8b6e2f6 100644
--- a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_embed.c
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_embed.c
@@ -8,16 +8,16 @@
 #include <assert.h>
 #include <string.h>
 
-#include "rss_comms_protocol_common.h"
-#include "rss_comms_protocol_embed.h"
+#include "rse_comms_protocol_common.h"
+#include "rse_comms_protocol_embed.h"
 
-psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_embed_serialize_msg(psa_handle_t handle,
 					      int16_t type,
 					      const struct psa_invec *in_vec,
 					      uint8_t in_len,
 					      const struct psa_outvec *out_vec,
 					      uint8_t out_len,
-					      struct rss_embed_msg_t *msg,
+					      struct rse_embed_msg_t *msg,
 					      size_t *msg_len)
 {
 	uint32_t payload_size = 0;
@@ -54,10 +54,10 @@
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_embed_deserialize_reply(struct psa_outvec *out_vec,
+psa_status_t rse_protocol_embed_deserialize_reply(struct psa_outvec *out_vec,
 						  uint8_t out_len,
 						  psa_status_t *return_val,
-						  const struct rss_embed_reply_t *reply,
+						  const struct rse_embed_reply_t *reply,
 						  size_t reply_size)
 {
 	uint32_t payload_offset = 0;
@@ -84,7 +84,7 @@
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_embed_calculate_msg_len(psa_handle_t handle,
+psa_status_t rse_protocol_embed_calculate_msg_len(psa_handle_t handle,
 						  const struct psa_invec *in_vec,
 						  uint8_t in_len,
 						  size_t *msg_len)
@@ -99,7 +99,7 @@
 		payload_size += in_vec[i].len;
 
 	/* Output the actual size of the message, to optimize sending */
-	*msg_len = offsetof(struct rss_embed_msg_t, trailer) + payload_size;
+	*msg_len = offsetof(struct rse_embed_msg_t, trailer) + payload_size;
 
 	return PSA_SUCCESS;
 }
diff --git a/components/rpc/rse_comms/caller/sp/rse_comms_protocol_embed.h b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_embed.h
new file mode 100644
index 0000000..e7f66b8
--- /dev/null
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_embed.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSE_COMMS_PROTOCOL_EMBED_H__
+#define __RSE_COMMS_PROTOCOL_EMBED_H__
+
+#include <psa/client.h>
+#include <sys/cdefs.h>
+
+struct __packed rse_embed_msg_t {
+	psa_handle_t handle;
+	uint32_t ctrl_param; /* type, in_len, out_len */
+	uint16_t io_size[PSA_MAX_IOVEC];
+	uint8_t trailer[PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE];
+};
+
+struct __packed rse_embed_reply_t {
+	int32_t return_val;
+	uint16_t out_size[PSA_MAX_IOVEC];
+	uint8_t trailer[PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE];
+};
+
+psa_status_t rse_protocol_embed_serialize_msg(psa_handle_t handle,
+					      int16_t type,
+					      const struct psa_invec *in_vec,
+					      uint8_t in_len,
+					      const struct psa_outvec *out_vec,
+					      uint8_t out_len,
+					      struct rse_embed_msg_t *msg,
+					      size_t *msg_len);
+
+psa_status_t rse_protocol_embed_deserialize_reply(struct psa_outvec *out_vec,
+						  uint8_t out_len,
+						  psa_status_t *return_val,
+						  const struct rse_embed_reply_t *reply,
+						  size_t reply_size);
+
+psa_status_t rse_protocol_embed_calculate_msg_len(psa_handle_t handle,
+						  const struct psa_invec *in_vec,
+						  uint8_t in_len,
+						  size_t *msg_len);
+
+#endif /* __RSE_COMMS_PROTOCOL_EMBED_H__ */
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_pointer_access.c b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_pointer_access.c
similarity index 78%
rename from components/rpc/rss_comms/caller/sp/rss_comms_protocol_pointer_access.c
rename to components/rpc/rse_comms/caller/sp/rse_comms_protocol_pointer_access.c
index 6d7d771..1bbdc3d 100644
--- a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_pointer_access.c
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_pointer_access.c
@@ -6,16 +6,16 @@
  */
 #include <assert.h>
 
-#include "rss_comms_protocol_common.h"
-#include "rss_comms_protocol_pointer_access.h"
+#include "rse_comms_protocol_common.h"
+#include "rse_comms_protocol_pointer_access.h"
 
-psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+psa_status_t rse_protocol_pointer_access_serialize_msg(psa_handle_t handle,
 						       int16_t type,
 						       const struct psa_invec *in_vec,
 						       uint8_t in_len,
 						       const struct psa_outvec *out_vec,
 						       uint8_t out_len,
-						       struct rss_pointer_access_msg_t *msg,
+						       struct rse_pointer_access_msg_t *msg,
 						       size_t *msg_len)
 {
 	unsigned int i;
@@ -42,10 +42,10 @@
 	return PSA_SUCCESS;
 }
 
-psa_status_t rss_protocol_pointer_access_deserialize_reply(struct psa_outvec *out_vec,
+psa_status_t rse_protocol_pointer_access_deserialize_reply(struct psa_outvec *out_vec,
 							   uint8_t out_len,
 							   psa_status_t *return_val,
-							   const struct rss_pointer_access_reply_t *reply,
+							   const struct rse_pointer_access_reply_t *reply,
 							   size_t reply_size)
 {
 	unsigned int i;
diff --git a/components/rpc/rse_comms/caller/sp/rse_comms_protocol_pointer_access.h b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_pointer_access.h
new file mode 100644
index 0000000..84845a9
--- /dev/null
+++ b/components/rpc/rse_comms/caller/sp/rse_comms_protocol_pointer_access.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__
+#define __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__
+
+
+#include <psa/client.h>
+#include <sys/cdefs.h>
+
+struct __packed rse_pointer_access_msg_t {
+	psa_handle_t handle;
+	uint32_t ctrl_param;
+	uint32_t io_sizes[PSA_MAX_IOVEC];
+	uint64_t host_ptrs[PSA_MAX_IOVEC];
+};
+
+struct __packed rse_pointer_access_reply_t {
+	int32_t return_val;
+	uint32_t out_sizes[PSA_MAX_IOVEC];
+};
+
+psa_status_t rse_protocol_pointer_access_serialize_msg(psa_handle_t handle,
+						       int16_t type,
+						       const struct psa_invec *in_vec,
+						       uint8_t in_len,
+						       const struct psa_outvec *out_vec,
+						       uint8_t out_len,
+						       struct rse_pointer_access_msg_t *msg,
+						       size_t *msg_len);
+
+psa_status_t rse_protocol_pointer_access_deserialize_reply(struct psa_outvec *out_vec,
+							   uint8_t out_len,
+							   psa_status_t *return_val,
+							   const struct rse_pointer_access_reply_t *reply,
+							   size_t reply_size);
+
+#endif /* __RSE_COMMS_PROTOCOL_POINTER_ACCESS_H__ */
diff --git a/components/rpc/rss_comms/component.cmake b/components/rpc/rse_comms/component.cmake
similarity index 62%
rename from components/rpc/rss_comms/component.cmake
rename to components/rpc/rse_comms/component.cmake
index 1cafb5c..fd6b4f3 100644
--- a/components/rpc/rss_comms/component.cmake
+++ b/components/rpc/rse_comms/component.cmake
@@ -9,15 +9,15 @@
 endif()
 
 set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
-	${CMAKE_CURRENT_LIST_DIR}/caller/sp/rss_comms_caller.h
+	${CMAKE_CURRENT_LIST_DIR}/caller/sp/rse_comms_caller.h
 	)
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/rss_comms.c"
-	"${CMAKE_CURRENT_LIST_DIR}/caller/sp/rss_comms_caller.c"
-	"${CMAKE_CURRENT_LIST_DIR}/caller/sp/rss_comms_protocol.c"
-	"${CMAKE_CURRENT_LIST_DIR}/caller/sp/rss_comms_protocol_embed.c"
-	"${CMAKE_CURRENT_LIST_DIR}/caller/sp/rss_comms_protocol_pointer_access.c"
+	"${CMAKE_CURRENT_LIST_DIR}/rse_comms.c"
+	"${CMAKE_CURRENT_LIST_DIR}/caller/sp/rse_comms_caller.c"
+	"${CMAKE_CURRENT_LIST_DIR}/caller/sp/rse_comms_protocol.c"
+	"${CMAKE_CURRENT_LIST_DIR}/caller/sp/rse_comms_protocol_embed.c"
+	"${CMAKE_CURRENT_LIST_DIR}/caller/sp/rse_comms_protocol_pointer_access.c"
 	)
 
 target_include_directories(${TGT}
diff --git a/components/rpc/rss_comms/rss_comms.c b/components/rpc/rse_comms/rse_comms.c
similarity index 80%
rename from components/rpc/rss_comms/rss_comms.c
rename to components/rpc/rse_comms/rse_comms.c
index 267d134..691c7ef 100644
--- a/components/rpc/rss_comms/rss_comms.c
+++ b/components/rpc/rse_comms/rse_comms.c
@@ -9,8 +9,8 @@
 
 #include "protocols/rpc/common/packed-c/status.h"
 #include "psa/client.h"
-#include "rss_comms_caller.h"
-#include "rss_comms_protocol.h"
+#include "rse_comms_caller.h"
+#include "rse_comms_protocol.h"
 #include "trace.h"
 
 /* This value should be set according to the implemented channels
@@ -37,12 +37,12 @@
 		out_size_total += out_vec[i].len;
 	}
 
-	comms_embed_msg_min_size = sizeof(struct serialized_rss_comms_header_t) +
-				   sizeof(struct rss_embed_msg_t) - PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
+	comms_embed_msg_min_size = sizeof(struct serialized_rse_comms_header_t) +
+				   sizeof(struct rse_embed_msg_t) - PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
 
-	comms_embed_reply_min_size = sizeof(struct serialized_rss_comms_header_t) +
-				     sizeof(struct rss_embed_reply_t) -
-				     PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE;
+	comms_embed_reply_min_size = sizeof(struct serialized_rse_comms_header_t) +
+				     sizeof(struct rse_embed_reply_t) -
+				     PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
 
 	/* Use embed if we can pack into one message and reply, else use
 	 * pointer_access. The underlying MHU transport protocol uses a
@@ -59,9 +59,9 @@
 	     COMMS_MHU_MSG_SIZE - sizeof(uint32_t)) ||
 	    (comms_embed_reply_min_size + out_size_total >
 	     COMMS_MHU_MSG_SIZE - sizeof(uint32_t))) {
-		return RSS_COMMS_PROTOCOL_POINTER_ACCESS;
+		return RSE_COMMS_PROTOCOL_POINTER_ACCESS;
 	} else {
-		return RSS_COMMS_PROTOCOL_EMBED;
+		return RSE_COMMS_PROTOCOL_EMBED;
 	}
 }
 
@@ -73,22 +73,22 @@
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
 	psa_status_t return_val = PSA_ERROR_INVALID_ARGUMENT;
-	rss_comms_call_handle rpc_handle = (rss_comms_call_handle)caller;
+	rse_comms_call_handle rpc_handle = (rse_comms_call_handle)caller;
 	size_t req_len = 0;
 	size_t resp_len = 0;
-	struct serialized_rss_comms_msg_t *req = NULL;
-	struct serialized_rss_comms_reply_t *reply = NULL;
+	struct serialized_rse_comms_msg_t *req = NULL;
+	struct serialized_rse_comms_reply_t *reply = NULL;
 	uint8_t protocol_ver = 0;
 
 	protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
 
-	psa_status = rss_protocol_calculate_msg_len(handle, protocol_ver, in_vec, in_len, &req_len);
+	psa_status = rse_protocol_calculate_msg_len(handle, protocol_ver, in_vec, in_len, &req_len);
 	if (psa_status != PSA_SUCCESS) {
 		EMSG("Message size calculation failed: %d", psa_status);
 		return psa_status;
 	}
 
-	rpc_handle = rss_comms_caller_begin(caller, (uint8_t **)&req, req_len);
+	rpc_handle = rse_comms_caller_begin(caller, (uint8_t **)&req, req_len);
 	if (!rpc_handle) {
 		EMSG("Could not get handle");
 		return PSA_ERROR_GENERIC_ERROR;
@@ -99,33 +99,33 @@
 	req->header.client_id = client_id;
 	req->header.protocol_ver = protocol_ver;
 
-	psa_status = rss_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec, out_len, req,
+	psa_status = rse_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec, out_len, req,
 						&req_len);
 	if (psa_status != PSA_SUCCESS) {
 		EMSG("Serialize msg failed: %d", psa_status);
 		return psa_status;
 	}
 
-	DMSG("Sending rss_comms message");
+	DMSG("Sending rse_comms message");
 	DMSG("protocol_ver=%u", req->header.protocol_ver);
 	DMSG("seq_num=%u", req->header.seq_num);
 	DMSG("client_id=%u", req->header.client_id);
 
 	resp_len = sizeof(*reply);
 
-	rpc_status = rss_comms_caller_invoke(rpc_handle, 0, (uint8_t **)&reply, &resp_len);
+	rpc_status = rse_comms_caller_invoke(rpc_handle, 0, (uint8_t **)&reply, &resp_len);
 	if (rpc_status != RPC_SUCCESS) {
 		EMSG("Invoke failed: %d", rpc_status);
 		return PSA_ERROR_GENERIC_ERROR;
 	}
 
-	DMSG("Received rss_comms reply");
+	DMSG("Received rse_comms reply");
 	DMSG("protocol_ver=%u", reply->header.protocol_ver);
 	DMSG("seq_num=%u", reply->header.seq_num);
 	DMSG("client_id=%u", reply->header.client_id);
 	DMSG("resp_len=%lu", resp_len);
 
-	psa_status = rss_protocol_deserialize_reply(out_vec, out_len, &return_val, reply, resp_len);
+	psa_status = rse_protocol_deserialize_reply(out_vec, out_len, &return_val, reply, resp_len);
 	if (psa_status != PSA_SUCCESS) {
 		EMSG("Protocol deserialize reply failed: %d", psa_status);
 		return psa_status;
@@ -133,7 +133,7 @@
 
 	DMSG("Return_val=%d", return_val);
 
-	rss_comms_caller_end(rpc_handle);
+	rse_comms_caller_end(rpc_handle);
 
 	seq_num++;
 
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_caller.h b/components/rpc/rss_comms/caller/sp/rss_comms_caller.h
deleted file mode 100644
index a62edb5..0000000
--- a/components/rpc/rss_comms/caller/sp/rss_comms_caller.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef __RSS_COMMS_CALLER_H__
-#define __RSS_COMMS_CALLER_H__
-
-#include "rpc_caller.h"
-#include "rss_comms_messenger_api.h"
-
-typedef void *rss_comms_call_handle;
-
-rpc_status_t rss_comms_caller_init(struct rpc_caller_interface *rpc_caller);
-rpc_status_t rss_comms_caller_deinit(struct rpc_caller_interface *rpc_caller);
-
-rss_comms_call_handle rss_comms_caller_begin(struct rpc_caller_interface *caller,
-					     uint8_t **request_buffer, size_t request_length);
-
-rpc_status_t rss_comms_caller_invoke(rss_comms_call_handle handle, uint32_t opcode,
-				     uint8_t **response_buffer, size_t *response_length);
-
-rpc_status_t rss_comms_caller_end(rss_comms_call_handle handle);
-
-#endif /* __RSS_COMMS_CALLER_H__ */
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_protocol.h b/components/rpc/rss_comms/caller/sp/rss_comms_protocol.h
deleted file mode 100644
index 2d597b4..0000000
--- a/components/rpc/rss_comms/caller/sp/rss_comms_protocol.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __RSS_COMMS_PROTOCOL_H__
-#define __RSS_COMMS_PROTOCOL_H__
-
-#include <stdint.h>
-
-#include <psa/client.h>
-#include "rss_comms_protocol_embed.h"
-#include "rss_comms_protocol_pointer_access.h"
-#include "service/common/include/psa/client.h"
-
-enum rss_comms_protocol_version_t {
-	RSS_COMMS_PROTOCOL_EMBED = 0,
-	RSS_COMMS_PROTOCOL_POINTER_ACCESS = 1,
-};
-
-struct __packed serialized_rss_comms_header_t {
-	uint8_t protocol_ver;
-	uint8_t seq_num;
-	uint16_t client_id;
-};
-
-/* MHU message passed from Host to RSS to deliver a PSA client call */
-struct __packed serialized_rss_comms_msg_t {
-	struct serialized_rss_comms_header_t header;
-	union __packed {
-		struct rss_embed_msg_t embed;
-		struct rss_pointer_access_msg_t pointer_access;
-	} msg;
-};
-
-/* MHU reply message to hold the PSA client reply result returned by RSS */
-struct __packed serialized_rss_comms_reply_t {
-	struct serialized_rss_comms_header_t header;
-	union __packed {
-		struct rss_embed_reply_t embed;
-		struct rss_pointer_access_reply_t pointer_access;
-	} reply;
-};
-
-psa_status_t rss_protocol_serialize_msg(psa_handle_t handle,
-					int16_t type,
-					const struct psa_invec *in_vec,
-					uint8_t in_len,
-					const struct psa_outvec *out_vec,
-					uint8_t out_len,
-					struct serialized_rss_comms_msg_t *msg,
-					size_t *msg_len);
-
-psa_status_t rss_protocol_deserialize_reply(struct psa_outvec *out_vec,
-					    uint8_t out_len,
-					    psa_status_t *return_val,
-					    const struct serialized_rss_comms_reply_t *reply,
-					    size_t reply_size);
-
-psa_status_t rss_protocol_calculate_msg_len(psa_handle_t handle,
-					    uint8_t protocol_ver,
-					    const struct psa_invec *in_vec,
-					    uint8_t in_len,
-					    size_t *msg_len);
-
-#endif /* __RSS_COMMS_PROTOCOL_H__ */
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_embed.h b/components/rpc/rss_comms/caller/sp/rss_comms_protocol_embed.h
deleted file mode 100644
index 29e2250..0000000
--- a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_embed.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __RSS_COMMS_PROTOCOL_EMBED_H__
-#define __RSS_COMMS_PROTOCOL_EMBED_H__
-
-#include <psa/client.h>
-#include <sys/cdefs.h>
-
-struct __packed rss_embed_msg_t {
-	psa_handle_t handle;
-	uint32_t ctrl_param; /* type, in_len, out_len */
-	uint16_t io_size[PSA_MAX_IOVEC];
-	uint8_t trailer[PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE];
-};
-
-struct __packed rss_embed_reply_t {
-	int32_t return_val;
-	uint16_t out_size[PSA_MAX_IOVEC];
-	uint8_t trailer[PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE];
-};
-
-psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
-					      int16_t type,
-					      const struct psa_invec *in_vec,
-					      uint8_t in_len,
-					      const struct psa_outvec *out_vec,
-					      uint8_t out_len,
-					      struct rss_embed_msg_t *msg,
-					      size_t *msg_len);
-
-psa_status_t rss_protocol_embed_deserialize_reply(struct psa_outvec *out_vec,
-						  uint8_t out_len,
-						  psa_status_t *return_val,
-						  const struct rss_embed_reply_t *reply,
-						  size_t reply_size);
-
-psa_status_t rss_protocol_embed_calculate_msg_len(psa_handle_t handle,
-						  const struct psa_invec *in_vec,
-						  uint8_t in_len,
-						  size_t *msg_len);
-
-#endif /* __RSS_COMMS_PROTOCOL_EMBED_H__ */
diff --git a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_pointer_access.h b/components/rpc/rss_comms/caller/sp/rss_comms_protocol_pointer_access.h
deleted file mode 100644
index a1b278c..0000000
--- a/components/rpc/rss_comms/caller/sp/rss_comms_protocol_pointer_access.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#ifndef __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
-#define __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__
-
-
-#include <psa/client.h>
-#include <sys/cdefs.h>
-
-struct __packed rss_pointer_access_msg_t {
-	psa_handle_t handle;
-	uint32_t ctrl_param;
-	uint32_t io_sizes[PSA_MAX_IOVEC];
-	uint64_t host_ptrs[PSA_MAX_IOVEC];
-};
-
-struct __packed rss_pointer_access_reply_t {
-	int32_t return_val;
-	uint32_t out_sizes[PSA_MAX_IOVEC];
-};
-
-psa_status_t rss_protocol_pointer_access_serialize_msg(psa_handle_t handle,
-						       int16_t type,
-						       const struct psa_invec *in_vec,
-						       uint8_t in_len,
-						       const struct psa_outvec *out_vec,
-						       uint8_t out_len,
-						       struct rss_pointer_access_msg_t *msg,
-						       size_t *msg_len);
-
-psa_status_t rss_protocol_pointer_access_deserialize_reply(struct psa_outvec *out_vec,
-							   uint8_t out_len,
-							   psa_status_t *return_val,
-							   const struct rss_pointer_access_reply_t *reply,
-							   size_t reply_size);
-
-#endif /* __RSS_COMMS_PROTOCOL_POINTER_ACCESS_H__ */
diff --git a/components/rpc/ts_rpc/caller/linux/component.cmake b/components/rpc/ts_rpc/caller/linux/component.cmake
index c9f439e..f8e4a52 100644
--- a/components/rpc/ts_rpc/caller/linux/component.cmake
+++ b/components/rpc/ts_rpc/caller/linux/component.cmake
@@ -8,8 +8,6 @@
 	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
 endif()
 
-include(${TS_ROOT}/external/LinuxFfaTeeDriver/LinuxFfaTeeDriver.cmake)
-
 set_property(TARGET ${TGT} APPEND PROPERTY PUBLIC_HEADER
 	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_caller_linux.h"
 	)
@@ -17,7 +15,3 @@
 target_sources(${TGT} PRIVATE
 	"${CMAKE_CURRENT_LIST_DIR}/ts_rpc_caller_linux.c"
 	)
-
-target_include_directories(${TGT} PRIVATE
-	"${LINUX_FFA_TEE_DRIVER_INCLUDE_DIR}"
-	)
diff --git a/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c b/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c
index 7c4606e..3402a9f 100644
--- a/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c
+++ b/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.c
@@ -6,7 +6,6 @@
 
 #include "ts_rpc_caller_linux.h"
 
-#include <arm_tstee.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <linux/tee.h>
@@ -24,11 +23,16 @@
 
 #define INVALID_SESS_ID		  0
 #define MAX_TEE_DEV_NUM		  16
-#define TS_TEE_DRV_REQ_VER_MAJOR  2
-#define TS_TEE_DRV_REQ_VER_MINOR  0
-#define TS_TEE_DRV_REQ_VER_PATCH  0
 #define TS_TEE_DRV_INVALID_SHM_ID (0)
 
+/*
+ * This define is part of linux/tee.h starting from Linux v6.10
+ * Let's keep a copy here in case the kernel headers come from an older version
+ */
+#ifndef TEE_IMPL_ID_TSTEE
+#define TEE_IMPL_ID_TSTEE 3
+#endif
+
 struct ts_tee_dev {
 	uint16_t endpoint_id;
 	char path[16];
@@ -236,47 +240,6 @@
 	return RPC_SUCCESS;
 }
 
-static bool ts_tee_drv_check_version(void)
-{
-	unsigned int major = 0;
-	unsigned int minor = 0;
-	unsigned int patch = 0;
-	FILE *f = NULL;
-	int cnt = 0;
-
-	f = fopen("/sys/module/arm_tstee/version", "r");
-	if (f) {
-		cnt = fscanf(f, "%u.%u.%u", &major, &minor, &patch);
-		fclose(f);
-
-		if (cnt != 3) {
-			printf("error: cannot read TS TEE driver version\n");
-			return false;
-		}
-	} else {
-		printf("error: TS TEE driver not available\n");
-		return false;
-	}
-
-	if (major != TS_TEE_DRV_REQ_VER_MAJOR)
-		goto err;
-
-	if (minor < TS_TEE_DRV_REQ_VER_MINOR)
-		goto err;
-
-	if (minor == TS_TEE_DRV_REQ_VER_MINOR)
-		if (patch < TS_TEE_DRV_REQ_VER_PATCH)
-			goto err;
-
-	return true;
-
-err:
-	printf("error: TS TEE driver is v%u.%u.%u but required v%u.%u.%u\n", major, minor, patch,
-	       TS_TEE_DRV_REQ_VER_MAJOR, TS_TEE_DRV_REQ_VER_MINOR, TS_TEE_DRV_REQ_VER_PATCH);
-
-	return false;
-}
-
 static void ts_tee_drv_discover(struct ts_tee_dev *ts_tee_devs, size_t count)
 {
 	struct tee_ioctl_version_data vers = { 0 };
@@ -314,9 +277,6 @@
 	if (!rpc_caller || rpc_caller->context)
 		return RPC_ERROR_INVALID_VALUE;
 
-	if (!ts_tee_drv_check_version())
-		return RPC_ERROR_INTERNAL;
-
 	context = (struct ts_rpc_caller_linux_context *)calloc(
 		1, sizeof(struct ts_rpc_caller_linux_context));
 	if (!context)
diff --git a/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h b/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h
index 26c6ce8..0ee77c8 100644
--- a/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h
+++ b/components/rpc/ts_rpc/caller/linux/ts_rpc_caller_linux.h
@@ -7,7 +7,7 @@
 #ifndef TS_RPC_CALLER_LINUX_H
 #define TS_RPC_CALLER_LINUX_H
 
-#include "components/rpc/common/caller/rpc_caller.h"
+#include "rpc_caller.h"
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.c b/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.c
index ffa3d9b..bd66050 100644
--- a/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.c
+++ b/components/rpc/ts_rpc/caller/sp/ts_rpc_caller_sp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -469,12 +469,22 @@
 rpc_status_t ts_rpc_caller_sp_init(struct rpc_caller_interface *rpc_caller)
 {
 	struct ts_rpc_caller_sp_context *context = NULL;
-	uint16_t own_id;
+	sp_result result = SP_RESULT_INTERNAL_ERROR;
+	uint16_t own_id = 0;
+	uint16_t major = 0;
+	uint16_t minor = 0;
 	uint8_t i = 0;
 
 	if (!rpc_caller || rpc_caller->context)
 		return RPC_ERROR_INVALID_VALUE;
 
+	result = sp_discovery_ffa_version_get(&major, &minor);
+	if (result != SP_RESULT_OK)
+		return RPC_ERROR_TRANSPORT_LAYER;
+
+	if (major != FFA_VERSION_MAJOR || minor < FFA_VERSION_MINOR)
+		return RPC_ERROR_TRANSPORT_LAYER;
+
 	if (sp_discovery_own_id_get(&own_id) != SP_RESULT_OK)
 		return RPC_ERROR_INTERNAL;
 
diff --git a/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.c b/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.c
index d001158..3888d0b 100644
--- a/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.c
+++ b/components/rpc/ts_rpc/endpoint/sp/ts_rpc_endpoint_sp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -245,10 +245,19 @@
 				     size_t shared_memory_count)
 {
 	sp_result result = SP_RESULT_OK;
+	uint16_t major = 0;
+	uint16_t minor = 0;
 
 	if (!endpoint || !service_count)
 		return RPC_ERROR_INVALID_VALUE;
 
+	result = sp_discovery_ffa_version_get(&major, &minor);
+	if (result != SP_RESULT_OK)
+		return RPC_ERROR_TRANSPORT_LAYER;
+
+	if (major != FFA_VERSION_MAJOR || minor < FFA_VERSION_MINOR)
+		return RPC_ERROR_TRANSPORT_LAYER;
+
 	result = sp_discovery_own_id_get(&endpoint->own_id);
 	if (result != SP_RESULT_OK)
 		return RPC_ERROR_TRANSPORT_LAYER;
diff --git a/components/service/attestation/include/provision/attest_provision.h b/components/service/attestation/include/provision/attest_provision.h
index 9f42920..ffde156 100644
--- a/components/service/attestation/include/provision/attest_provision.h
+++ b/components/service/attestation/include/provision/attest_provision.h
@@ -1,13 +1,13 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  */
 
+#include <psa/error.h>
 #include <stddef.h>
 #include <stdint.h>
-#include <psa/error.h>
 
 #ifndef ATTEST_PROVISION_H
 #define ATTEST_PROVISION_H
@@ -22,6 +22,12 @@
 extern "C" {
 #endif
 
+#ifdef EXPORT_PUBLIC_INTERFACE_PSA_ATTEST
+#define PSA_ATTEST_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define PSA_ATTEST_EXPORTED
+#endif
+
 /**
  * \brief Export IAK public key
  *
@@ -36,10 +42,9 @@
  *
  * \return Returns error code as specified in \ref psa_status_t
  */
-psa_status_t attest_provision_export_iak_public_key(
-    uint8_t *data,
-    size_t data_size,
-    size_t *data_length);
+PSA_ATTEST_EXPORTED psa_status_t attest_provision_export_iak_public_key(uint8_t *data,
+									size_t data_size,
+									size_t *data_length);
 
 /**
  * \brief Import IAK
@@ -58,9 +63,8 @@
  *
  * \return Returns error code as specified in \ref psa_status_t
  */
-psa_status_t attest_provision_import_iak(
-    const uint8_t *data,
-    size_t data_length);
+PSA_ATTEST_EXPORTED psa_status_t attest_provision_import_iak(const uint8_t *data,
+							     size_t data_length);
 
 /**
  * \brief Check if IAK exists
@@ -69,7 +73,7 @@
  *
  * \return Returns PSA_SUCCESS if IAK exists, PSA_ERROR_DOES_NOT_EXIST if not
  */
-psa_status_t attest_provision_iak_exists(void);
+PSA_ATTEST_EXPORTED psa_status_t attest_provision_iak_exists(void);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/attestation/include/psa/initial_attestation.h b/components/service/attestation/include/psa/initial_attestation.h
index 7b44220..3aacb29 100644
--- a/components/service/attestation/include/psa/initial_attestation.h
+++ b/components/service/attestation/include/psa/initial_attestation.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -16,15 +16,21 @@
 #define __PSA_INITIAL_ATTESTATION_H__
 
 #include <limits.h>
-#include <stdint.h>
-#include <stddef.h>
 #include <psa/crypto.h>
 #include <psa/error.h>
+#include <stddef.h>
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#ifdef EXPORT_PUBLIC_INTERFACE_PSA_ATTEST
+#define PSA_ATTEST_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define PSA_ATTEST_EXPORTED
+#endif
+
 /**
  * \brief PSA INITIAL ATTESTATION API version
  *
@@ -38,16 +44,16 @@
  * Challenge can be a nonce from server
  * or the hash of some combined data : nonce + attested data by caller.
  */
-#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32  (32u)
-#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48  (48u)
-#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64  (64u)
+#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_32 (32u)
+#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_48 (48u)
+#define PSA_INITIAL_ATTEST_CHALLENGE_SIZE_64 (64u)
 
 /**
  * The maximum size of an attestation token that can be generated by the
  * attestation service. Used to configure buffers for services that verify the
  * produced tokens.
  */
-#define PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE   (4096)
+#define PSA_INITIAL_ATTEST_MAX_TOKEN_SIZE (4096)
 
 /**
  * The list of fixed claims in the initial attestation token is still evolving,
@@ -178,12 +184,11 @@
  *
  * \return Returns error code as specified in \ref psa_status_t
  */
-psa_status_t
-psa_initial_attest_get_token(const uint8_t *auth_challenge,
-                             size_t         challenge_size,
-                             uint8_t       *token_buf,
-                             size_t         token_buf_size,
-                             size_t        *token_size);
+PSA_ATTEST_EXPORTED psa_status_t psa_initial_attest_get_token(const uint8_t *auth_challenge,
+							      size_t challenge_size,
+							      uint8_t *token_buf,
+							      size_t token_buf_size,
+							      size_t *token_size);
 
 /**
  * \brief Get the exact size of initial attestation token in bytes.
@@ -198,9 +203,8 @@
  *
  * \return Returns error code as specified in \ref psa_status_t
  */
-psa_status_t
-psa_initial_attest_get_token_size(size_t  challenge_size,
-                                  size_t *token_size);
+PSA_ATTEST_EXPORTED psa_status_t psa_initial_attest_get_token_size(size_t challenge_size,
+								   size_t *token_size);
 
 /**
  * \brief Get the attestation public key
@@ -220,11 +224,9 @@
  *
  * \return Returns error code as specified in \ref psa_status_t
  */
-psa_status_t
-tfm_initial_attest_get_public_key(uint8_t         *public_key,
-                                  size_t           public_key_buf_size,
-                                  size_t          *public_key_len,
-                                  psa_ecc_family_t *elliptic_curve_type);
+PSA_ATTEST_EXPORTED psa_status_t
+tfm_initial_attest_get_public_key(uint8_t *public_key, size_t public_key_buf_size,
+				  size_t *public_key_len, psa_ecc_family_t *elliptic_curve_type);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/block_storage/block_store/storage_partition_acl.c b/components/service/block_storage/block_store/storage_partition_acl.c
index 127fc2e..fb8ba4f 100644
--- a/components/service/block_storage/block_store/storage_partition_acl.c
+++ b/components/service/block_storage/block_store/storage_partition_acl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -33,15 +33,13 @@
 	struct storage_partition_acl *acl,
 	const char *owner_id)
 {
-	size_t len = strlen(owner_id);
+	size_t len = strlen(owner_id) + 1;
 
-	if (len < STORAGE_PARTITION_ACL_MAX_OWNER_ID_LEN) {
+	if (len > sizeof(acl->owner_id))
+		return false;
 
-		strcpy(acl->owner_id, owner_id);
-		return true;
-	}
-
-	return false;
+	memcpy(acl->owner_id, owner_id, len);
+	return true;
 }
 
 bool storage_partition_acl_check(
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/service/crypto/backend/mbedcrypto/trng_adapter/stub/component.cmake
similarity index 72%
copy from components/service/fwu/provider/serializer/packed-c/component.cmake
copy to components/service/crypto/backend/mbedcrypto/trng_adapter/stub/component.cmake
index 4209cae..8a5d8c9 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/stub/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
+	"${CMAKE_CURRENT_LIST_DIR}/stub_trng_adapter.c"
 	)
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/stub/stub_trng_adapter.c b/components/service/crypto/backend/mbedcrypto/trng_adapter/stub/stub_trng_adapter.c
new file mode 100644
index 0000000..07d0702
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/stub/stub_trng_adapter.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include <mbedtls/entropy.h>
+#include <service/crypto/backend/mbedcrypto/trng_adapter/trng_adapter.h>
+#include <psa/error.h>
+#include <stddef.h>
+
+int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen)
+{
+    (void)data;
+    (void)output;
+    (void)len;
+    (void)olen;
+
+    return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
+}
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/test/component.cmake b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/component.cmake
index 4aa4321..67a2ee8 100644
--- a/components/service/crypto/backend/mbedcrypto/trng_adapter/test/component.cmake
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/component.cmake
@@ -12,3 +12,6 @@
 	"${CMAKE_CURRENT_LIST_DIR}/trng_env_tests.c"
 	)
 
+target_include_directories(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}"
+	)
diff --git a/components/service/crypto/backend/mbedcrypto/trng_adapter/test/mbedtls/entropy.h b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/mbedtls/entropy.h
new file mode 100644
index 0000000..4f115a6
--- /dev/null
+++ b/components/service/crypto/backend/mbedcrypto/trng_adapter/test/mbedtls/entropy.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ENTROPY_H
+#define ENTROPY_H
+
+/*
+ * This macro is only used for baremetal testing. It is set to a random value,
+ * which is unrelated to mbedtls to avoid the need of keeping it syncronized.
+ */
+#define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED (0xFFFF)
+
+#endif /* ENTROPY_H */
diff --git a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
index 27ac598..f9bbf84 100644
--- a/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
+++ b/components/service/crypto/backend/psa_ipc/crypto_ipc_backend.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -44,7 +44,7 @@
                               *   See tfm_crypto_func_sid for detail
                               */
     uint16_t step;           /*!< Key derivation step */
-}__packed;
+} __attribute__((__packed__));
 
 #define iov_size sizeof(struct psa_ipc_crypto_pack_iovec)
 
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller.h b/components/service/crypto/client/caller/packed-c/crypto_caller.h
index d834bc2..d5dd0f7 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller.h
@@ -31,5 +31,6 @@
 #include "crypto_caller_sign_hash.h"
 #include "crypto_caller_verify_hash.h"
 #include "crypto_caller_verify_pkcs7_signature.h"
+#include "crypto_caller_get_uefi_priv_auth_var_fingerprint.h"
 
 #endif /* PACKEDC_CRYPTO_CALLER_H */
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
index bf39762..417189e 100644
--- a/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_aead.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -430,7 +430,10 @@
 
 					if (decoded_record.length <= aeadtext_size) {
 
-						memcpy(aeadtext, decoded_record.value, decoded_record.length);
+						if (decoded_record.length && aeadtext)
+							memcpy(aeadtext, decoded_record.value,
+							       decoded_record.length);
+
 						*aeadtext_length = decoded_record.length;
 					}
 					else {
@@ -528,7 +531,10 @@
 
 					if (decoded_record.length <= plaintext_size) {
 
-						memcpy(plaintext, decoded_record.value, decoded_record.length);
+						if (decoded_record.length && plaintext)
+							memcpy(plaintext, decoded_record.value,
+							       decoded_record.length);
+
 						*plaintext_length = decoded_record.length;
 					}
 					else {
diff --git a/components/service/crypto/client/caller/packed-c/crypto_caller_get_uefi_priv_auth_var_fingerprint.h b/components/service/crypto/client/caller/packed-c/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
new file mode 100644
index 0000000..73825b9
--- /dev/null
+++ b/components/service/crypto/client/caller/packed-c/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PACKEDC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+#define PACKEDC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+
+#include <common/tlv/tlv.h>
+#include <protocols/common/efi/efi_status.h>
+#include <protocols/rpc/common/packed-c/status.h>
+#include <protocols/service/crypto/packed-c/opcodes.h>
+#include <protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h>
+#include <service/common/client/service_client.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline int crypto_caller_get_uefi_priv_auth_var_fingerprint(struct service_client *context,
+						       const uint8_t *signature_cert,
+						       uint64_t signature_cert_len,
+						       uint8_t *output)
+{
+	efi_status_t efi_status = EFI_INVALID_PARAMETER;
+	size_t req_len = 0;
+
+	if (signature_cert_len > UINT16_MAX)
+		return efi_status;
+
+	struct tlv_record signature_record = {
+		.tag = TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_IN_TAG_SIGNATURE,
+		.length = (uint16_t)signature_cert_len,
+		.value = signature_cert
+	};
+
+	req_len += tlv_required_space(signature_record.length);
+
+	rpc_call_handle call_handle;
+	uint8_t *req_buf;
+
+	call_handle = rpc_caller_session_begin(context->session, &req_buf, req_len, 0);
+
+	if (call_handle) {
+		uint8_t *resp_buf;
+		size_t resp_len;
+		service_status_t service_status;
+		struct tlv_iterator req_iter;
+
+		tlv_iterator_begin(&req_iter, req_buf, req_len);
+		if (!tlv_encode(&req_iter, &signature_record))
+			return efi_status;
+
+		context->rpc_status = rpc_caller_session_invoke(
+			call_handle, TS_CRYPTO_OPCODE_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT, &resp_buf, &resp_len,
+			&service_status);
+
+		efi_status = (efi_status_t)service_status;
+
+		if (context->rpc_status == RPC_SUCCESS) {
+
+			if (efi_status == EFI_SUCCESS) {
+
+				struct tlv_const_iterator resp_iter;
+				struct tlv_record decoded_record;
+				tlv_const_iterator_begin(&resp_iter, resp_buf, resp_len);
+
+				if (tlv_find_decode(&resp_iter,
+							TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_OUT_TAG_IDENTIFIER, &decoded_record)) {
+
+					memcpy(output, decoded_record.value, PSA_HASH_MAX_SIZE);
+					efi_status = EFI_SUCCESS;
+				} else {
+					/* Mandatory response parameter missing */
+					efi_status = EFI_PROTOCOL_ERROR;
+				}
+			}
+		}
+
+		rpc_caller_session_end(call_handle);
+	}
+
+	return efi_status;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PACKEDC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H */
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller.h
index 68d489f..5821f13 100644
--- a/components/service/crypto/client/caller/psa_ipc/crypto_caller.h
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller.h
@@ -23,6 +23,7 @@
 #include "crypto_caller_generate_key.h"
 #include "crypto_caller_generate_random.h"
 #include "crypto_caller_get_key_attributes.h"
+#include "crypto_caller_get_uefi_priv_auth_var_fingerprint.h"
 #include "crypto_caller_hash.h"
 #include "crypto_caller_import_key.h"
 #include "crypto_caller_key_derivation.h"
diff --git a/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_uefi_priv_auth_var_fingerprint.h b/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
new file mode 100644
index 0000000..04e87ad
--- /dev/null
+++ b/components/service/crypto/client/caller/psa_ipc/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef PSA_IPC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+#define PSA_IPC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+
+#include <rpc/common/interface/rpc_status.h>
+#include <service/common/client/service_client.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline int crypto_caller_get_uefi_priv_auth_var_fingerprint(struct service_client *context,
+								   const uint8_t *signature_cert,
+								   uint64_t signature_cert_len,
+								   uint8_t *output)
+{
+	(void)context;
+	(void)signature_cert;
+	(void)signature_cert_len;
+	(void)output;
+
+	return RPC_ERROR_INTERNAL;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_IPC_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H */
diff --git a/components/service/crypto/client/caller/stub/crypto_caller.h b/components/service/crypto/client/caller/stub/crypto_caller.h
index 1931d02..0e88a13 100644
--- a/components/service/crypto/client/caller/stub/crypto_caller.h
+++ b/components/service/crypto/client/caller/stub/crypto_caller.h
@@ -26,6 +26,7 @@
 #include "crypto_caller_asymmetric_encrypt.h"
 #include "crypto_caller_export_key.h"
 #include "crypto_caller_get_key_attributes.h"
+#include "crypto_caller_get_uefi_priv_auth_var_fingerprint.h"
 #include "crypto_caller_sign_hash.h"
 #include "crypto_caller_cipher.h"
 #include "crypto_caller_export_public_key.h"
diff --git a/components/service/crypto/client/caller/stub/crypto_caller_get_uefi_priv_auth_var_fingerprint.h b/components/service/crypto/client/caller/stub/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
new file mode 100644
index 0000000..d8c286b
--- /dev/null
+++ b/components/service/crypto/client/caller/stub/crypto_caller_get_uefi_priv_auth_var_fingerprint.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef STUB_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+#define STUB_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+
+#include <rpc/common/interface/rpc_status.h>
+#include <service/common/client/service_client.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline int crypto_caller_get_uefi_priv_auth_var_fingerprint(struct service_client *context,
+								   const uint8_t *signature_cert,
+								   uint64_t signature_cert_len,
+								   uint8_t *output)
+{
+	(void)context;
+	(void)signature_cert;
+	(void)signature_cert_len;
+	(void)output;
+
+	return RPC_ERROR_INTERNAL;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STUB_CRYPTO_CALLER_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H */
diff --git a/components/service/crypto/client/cpp/crypto_client.h b/components/service/crypto/client/cpp/crypto_client.h
index 6792a17..80fbe24 100644
--- a/components/service/crypto/client/cpp/crypto_client.h
+++ b/components/service/crypto/client/cpp/crypto_client.h
@@ -240,6 +240,10 @@
 					   uint64_t hash_len, const uint8_t *public_key_cert,
 					   uint64_t public_key_cert_len) = 0;
 
+	virtual int get_uefi_priv_auth_var_fingerprint(const uint8_t *signature_cert,
+						       uint64_t signature_cert_len,
+						       uint8_t *output) = 0;
+
 protected:
 	crypto_client();
 	crypto_client(struct rpc_caller_session *session);
diff --git a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
index aaa71f0..4791feb 100644
--- a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.cpp
@@ -428,3 +428,12 @@
 						    hash, hash_len, public_key_cert,
 						    public_key_cert_len);
 }
+
+int packedc_crypto_client::get_uefi_priv_auth_var_fingerprint(const uint8_t *signature_cert,
+						  uint64_t signature_cert_len,
+						  uint8_t *output)
+{
+	return crypto_caller_get_uefi_priv_auth_var_fingerprint(&m_client, signature_cert,
+								signature_cert_len,
+								output);
+}
diff --git a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
index 8d4f60c..ec6c51c 100644
--- a/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
+++ b/components/service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h
@@ -236,6 +236,10 @@
 	int verify_pkcs7_signature(const uint8_t *signature_cert, uint64_t signature_cert_len,
 				   const uint8_t *hash, uint64_t hash_len,
 				   const uint8_t *public_key_cert, uint64_t public_key_cert_len);
+
+	int get_uefi_priv_auth_var_fingerprint(const uint8_t *signature_cert,
+				    uint64_t signature_cert_len,
+				    uint8_t *output);
 };
 
 #endif /* PACKEDC_CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
index 6bae7a8..1170255 100644
--- a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
+++ b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.cpp
@@ -1174,3 +1174,14 @@
 
 	return PSA_ERROR_NOT_SUPPORTED;
 }
+
+int protobuf_crypto_client::get_uefi_priv_auth_var_fingerprint(const uint8_t *signature_cert,
+							       uint64_t signature_cert_len,
+							       uint8_t *output)
+{
+	(void)signature_cert;
+	(void)signature_cert_len;
+	(void)output;
+
+	return PSA_ERROR_NOT_SUPPORTED;
+}
diff --git a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
index 9ad43f7..52f8a02 100644
--- a/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
+++ b/components/service/crypto/client/cpp/protocol/protobuf/protobuf_crypto_client.h
@@ -237,6 +237,10 @@
 				   const uint8_t *hash, uint64_t hash_len,
 				   const uint8_t *public_key_cert, uint64_t public_key_cert_len);
 
+	int get_uefi_priv_auth_var_fingerprint(const uint8_t *signature_cert,
+					       uint64_t signature_cert_len,
+					       uint8_t *output);
+
 private:
 
 	psa_status_t asym_sign(uint32_t opcode,
diff --git a/components/service/crypto/client/psa/component.cmake b/components/service/crypto/client/psa/component.cmake
index 359db3b..5bee0c6 100644
--- a/components/service/crypto/client/psa/component.cmake
+++ b/components/service/crypto/client/psa/component.cmake
@@ -32,4 +32,5 @@
 	"${CMAKE_CURRENT_LIST_DIR}/psa_sign_message.c"
 	"${CMAKE_CURRENT_LIST_DIR}/psa_verify_message.c"
 	"${CMAKE_CURRENT_LIST_DIR}/verify_pkcs7_signature.c"
+	"${CMAKE_CURRENT_LIST_DIR}/get_uefi_priv_auth_var_fingerprint.c"
 	)
diff --git a/components/service/crypto/client/psa/crypto_client.h b/components/service/crypto/client/psa/crypto_client.h
index 4b59bbe..af04df1 100644
--- a/components/service/crypto/client/psa/crypto_client.h
+++ b/components/service/crypto/client/psa/crypto_client.h
@@ -7,10 +7,15 @@
 #ifndef CRYPTO_CLIENT_H
 #define CRYPTO_CLIENT_H
 
+#include <stddef.h>
 #include <stdint.h>
 
 int verify_pkcs7_signature(const uint8_t *signature_cert, uint64_t signature_cert_len,
 			   const uint8_t *hash, uint64_t hash_len, const uint8_t *public_key_cert,
 			   uint64_t public_key_cert_len);
 
+int get_uefi_priv_auth_var_fingerprint_handler(const uint8_t *signature_cert,
+				    uint64_t signature_cert_len,
+				    uint8_t *output);
+
 #endif /* CRYPTO_CLIENT_H */
diff --git a/components/service/crypto/client/psa/get_uefi_priv_auth_var_fingerprint.c b/components/service/crypto/client/psa/get_uefi_priv_auth_var_fingerprint.c
new file mode 100644
index 0000000..702aaa0
--- /dev/null
+++ b/components/service/crypto/client/psa/get_uefi_priv_auth_var_fingerprint.c
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "crypto_caller_selector.h"
+#include "crypto_client.h"
+#include "psa_crypto_client.h"
+
+int get_uefi_priv_auth_var_fingerprint_handler(const uint8_t *signature_cert,
+				    uint64_t signature_cert_len,
+				    uint8_t *output)
+{
+	if (psa_crypto_client_instance.init_status != PSA_SUCCESS)
+		return psa_crypto_client_instance.init_status;
+
+	return crypto_caller_get_uefi_priv_auth_var_fingerprint(&psa_crypto_client_instance.base,
+						    signature_cert, signature_cert_len,
+						    output);
+}
diff --git a/components/service/crypto/client/psa/psa_crypto_client.c b/components/service/crypto/client/psa/psa_crypto_client.c
index e42d37a..d82e908 100644
--- a/components/service/crypto/client/psa/psa_crypto_client.c
+++ b/components/service/crypto/client/psa/psa_crypto_client.c
@@ -1,12 +1,14 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
-#include <stddef.h>
 #include "psa_crypto_client.h"
 
+#include <service/crypto/include/psa/crypto.h>
+#include <stddef.h>
+
 struct psa_crypto_client psa_crypto_client_instance = {
 
 	.base.session = NULL,
@@ -17,8 +19,8 @@
 	.init_status = PSA_ERROR_BAD_STATE
 };
 
-psa_status_t psa_crypto_init(void) {
-
+psa_status_t psa_crypto_init(void)
+{
 	/* Must be called after psa_crypto_client_init */
 	if (psa_crypto_client_instance.base.session)
 		psa_crypto_client_instance.init_status = PSA_SUCCESS;
diff --git a/components/service/crypto/include/psa/crypto.h b/components/service/crypto/include/psa/crypto.h
index b6e3aba..cd5b374 100644
--- a/components/service/crypto/include/psa/crypto.h
+++ b/components/service/crypto/include/psa/crypto.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -18,6 +18,12 @@
 extern "C" {
 #endif
 
+#ifdef EXPORT_PUBLIC_INTERFACE_PSA_CRYPTO
+#define PSA_CRYPTO_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define PSA_CRYPTO_EXPORTED
+#endif
+
 /* The file "crypto_types.h" declares types that encode errors,
  * algorithms, key types, policies, etc. */
 #include "psa/crypto_types.h"
@@ -74,7 +80,7 @@
  * \retval #PSA_ERROR_DATA_INVALID
  * \retval #PSA_ERROR_DATA_CORRUPT
  */
-psa_status_t psa_crypto_init(void);
+PSA_CRYPTO_EXPORTED psa_status_t psa_crypto_init(void);
 
 /**@}*/
 
@@ -118,8 +124,7 @@
  * \param[out] attributes  The attribute structure to write to.
  * \param key              The persistent identifier for the key.
  */
-static void psa_set_key_id( psa_key_attributes_t *attributes,
-                            psa_key_id_t key );
+static void psa_set_key_id(psa_key_attributes_t *attributes, psa_key_id_t key);
 
 /** Set the location of a persistent key.
  *
@@ -146,8 +151,7 @@
  *                              key will be volatile, and the key identifier
  *                              attribute is reset to 0.
  */
-static void psa_set_key_lifetime(psa_key_attributes_t *attributes,
-                                 psa_key_lifetime_t lifetime);
+static void psa_set_key_lifetime(psa_key_attributes_t *attributes, psa_key_lifetime_t lifetime);
 
 /** Retrieve the key identifier from key attributes.
  *
@@ -161,8 +165,7 @@
  *         This value is unspecified if the attribute structure declares
  *         the key as volatile.
  */
-static psa_key_id_t psa_get_key_id(
-    const psa_key_attributes_t *attributes);
+static psa_key_id_t psa_get_key_id(const psa_key_attributes_t *attributes);
 
 /** Retrieve the lifetime from key attributes.
  *
@@ -174,8 +177,7 @@
  *
  * \return The lifetime value stored in the attribute structure.
  */
-static psa_key_lifetime_t psa_get_key_lifetime(
-    const psa_key_attributes_t *attributes);
+static psa_key_lifetime_t psa_get_key_lifetime(const psa_key_attributes_t *attributes);
 
 /** Declare usage flags for a key.
  *
@@ -193,8 +195,7 @@
  * \param[out] attributes       The attribute structure to write to.
  * \param usage_flags           The usage flags to write.
  */
-static void psa_set_key_usage_flags(psa_key_attributes_t *attributes,
-                                    psa_key_usage_t usage_flags);
+static void psa_set_key_usage_flags(psa_key_attributes_t *attributes, psa_key_usage_t usage_flags);
 
 /** Retrieve the usage flags from key attributes.
  *
@@ -206,8 +207,7 @@
  *
  * \return The usage flags stored in the attribute structure.
  */
-static psa_key_usage_t psa_get_key_usage_flags(
-    const psa_key_attributes_t *attributes);
+static psa_key_usage_t psa_get_key_usage_flags(const psa_key_attributes_t *attributes);
 
 /** Declare the permitted algorithm policy for a key.
  *
@@ -239,9 +239,7 @@
  * \param[out] attributes       The attribute structure to write to.
  * \param alg                   The permitted algorithm policy to write.
  */
-static void psa_set_key_algorithm(psa_key_attributes_t *attributes,
-                                  psa_algorithm_t alg);
-
+static void psa_set_key_algorithm(psa_key_attributes_t *attributes, psa_algorithm_t alg);
 
 /** Retrieve the algorithm policy from key attributes.
  *
@@ -253,8 +251,7 @@
  *
  * \return The algorithm stored in the attribute structure.
  */
-static psa_algorithm_t psa_get_key_algorithm(
-    const psa_key_attributes_t *attributes);
+static psa_algorithm_t psa_get_key_algorithm(const psa_key_attributes_t *attributes);
 
 /** Declare the type of a key.
  *
@@ -270,9 +267,7 @@
  *                              If this is 0, the key type in \p attributes
  *                              becomes unspecified.
  */
-static void psa_set_key_type(psa_key_attributes_t *attributes,
-                             psa_key_type_t type);
-
+static void psa_set_key_type(psa_key_attributes_t *attributes, psa_key_type_t type);
 
 /** Declare the size of a key.
  *
@@ -288,8 +283,7 @@
  *                              becomes unspecified. Keys of size 0 are
  *                              not supported.
  */
-static void psa_set_key_bits(psa_key_attributes_t *attributes,
-                             size_t bits);
+static void psa_set_key_bits(psa_key_attributes_t *attributes, size_t bits);
 
 /** Retrieve the key type from key attributes.
  *
@@ -343,8 +337,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_get_key_attributes(psa_key_id_t key,
-                                    psa_key_attributes_t *attributes);
+PSA_CRYPTO_EXPORTED psa_status_t psa_get_key_attributes(psa_key_id_t key,
+							psa_key_attributes_t *attributes);
 
 /** Reset a key attribute structure to a freshly initialized state.
  *
@@ -358,7 +352,7 @@
  *
  * \param[in,out] attributes    The attribute structure to reset.
  */
-void psa_reset_key_attributes(psa_key_attributes_t *attributes);
+PSA_CRYPTO_EXPORTED void psa_reset_key_attributes(psa_key_attributes_t *attributes);
 
 /**@}*/
 
@@ -387,7 +381,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_purge_key(psa_key_id_t key);
+PSA_CRYPTO_EXPORTED psa_status_t psa_purge_key(psa_key_id_t key);
 
 /** Make a copy of a key.
  *
@@ -480,10 +474,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_copy_key(psa_key_id_t source_key,
-                          const psa_key_attributes_t *attributes,
-                          psa_key_id_t *target_key);
-
+PSA_CRYPTO_EXPORTED psa_status_t psa_copy_key(psa_key_id_t source_key,
+					      const psa_key_attributes_t *attributes,
+					      psa_key_id_t *target_key);
 
 /**
  * \brief Destroy a key.
@@ -530,7 +523,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_destroy_key(psa_key_id_t key);
+PSA_CRYPTO_EXPORTED psa_status_t psa_destroy_key(psa_key_id_t key);
 
 /**@}*/
 
@@ -611,12 +604,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
-                            const uint8_t *data,
-                            size_t data_length,
-                            psa_key_id_t *key);
-
-
+PSA_CRYPTO_EXPORTED psa_status_t psa_import_key(const psa_key_attributes_t *attributes,
+						const uint8_t *data, size_t data_length,
+						psa_key_id_t *key);
 
 /**
  * \brief Export a key in binary format.
@@ -704,10 +694,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_export_key(psa_key_id_t key,
-                            uint8_t *data,
-                            size_t data_size,
-                            size_t *data_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_export_key(psa_key_id_t key, uint8_t *data, size_t data_size,
+						size_t *data_length);
 
 /**
  * \brief Export a public key or the public part of a key pair in binary format.
@@ -774,12 +762,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_export_public_key(psa_key_id_t key,
-                                   uint8_t *data,
-                                   size_t data_size,
-                                   size_t *data_length);
-
-
+PSA_CRYPTO_EXPORTED psa_status_t psa_export_public_key(psa_key_id_t key, uint8_t *data,
+						       size_t data_size, size_t *data_length);
 
 /**@}*/
 
@@ -819,12 +803,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_compute(psa_algorithm_t alg,
-                              const uint8_t *input,
-                              size_t input_length,
-                              uint8_t *hash,
-                              size_t hash_size,
-                              size_t *hash_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_compute(psa_algorithm_t alg, const uint8_t *input,
+						  size_t input_length, uint8_t *hash,
+						  size_t hash_size, size_t *hash_length);
 
 /** Calculate the hash (digest) of a message and compare it with a
  * reference value.
@@ -855,11 +836,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_compare(psa_algorithm_t alg,
-                              const uint8_t *input,
-                              size_t input_length,
-                              const uint8_t *hash,
-                              size_t hash_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_compare(psa_algorithm_t alg, const uint8_t *input,
+						  size_t input_length, const uint8_t *hash,
+						  size_t hash_length);
 
 /** The type of the state data structure for multipart hash operations.
  *
@@ -956,8 +935,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
-                            psa_algorithm_t alg);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_setup(psa_hash_operation_t *operation,
+						psa_algorithm_t alg);
 
 /** Add a message fragment to a multipart hash operation.
  *
@@ -983,9 +962,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_update(psa_hash_operation_t *operation,
-                             const uint8_t *input,
-                             size_t input_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_update(psa_hash_operation_t *operation,
+						 const uint8_t *input, size_t input_length);
 
 /** Finish the calculation of the hash of a message.
  *
@@ -1030,10 +1008,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_finish(psa_hash_operation_t *operation,
-                             uint8_t *hash,
-                             size_t hash_size,
-                             size_t *hash_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_finish(psa_hash_operation_t *operation, uint8_t *hash,
+						 size_t hash_size, size_t *hash_length);
 
 /** Finish the calculation of the hash of a message and compare it with
  * an expected value.
@@ -1072,9 +1048,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
-                             const uint8_t *hash,
-                             size_t hash_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
+						 const uint8_t *hash, size_t hash_length);
 
 /** Abort a hash operation.
  *
@@ -1101,7 +1076,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_abort(psa_hash_operation_t *operation);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_abort(psa_hash_operation_t *operation);
 
 /** Clone a hash operation.
  *
@@ -1132,8 +1107,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
-                            psa_hash_operation_t *target_operation);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_clone(const psa_hash_operation_t *source_operation,
+						psa_hash_operation_t *target_operation);
 
 /** Suspend a hash operation.
  *
@@ -1155,10 +1130,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_suspend(psa_hash_operation_t *operation,
-                              uint8_t *hash_state,
-                              size_t hash_state_size,
-                              size_t *hash_state_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_suspend(psa_hash_operation_t *operation,
+						  uint8_t *hash_state, size_t hash_state_size,
+						  size_t *hash_state_length);
 
 /** Resume a hash operation.
  *
@@ -1182,9 +1156,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_hash_resume(psa_hash_operation_t *operation,
-                             const uint8_t *hash_state,
-                             size_t hash_state_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_hash_resume(psa_hash_operation_t *operation,
+						 const uint8_t *hash_state,
+						 size_t hash_state_length);
 
 /**@}*/
 
@@ -1234,13 +1208,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_compute(psa_key_id_t key,
-                             psa_algorithm_t alg,
-                             const uint8_t *input,
-                             size_t input_length,
-                             uint8_t *mac,
-                             size_t mac_size,
-                             size_t *mac_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_mac_compute(psa_key_id_t key, psa_algorithm_t alg,
+						 const uint8_t *input, size_t input_length,
+						 uint8_t *mac, size_t mac_size, size_t *mac_length);
 
 /** Calculate the MAC of a message and compare it with a reference value.
  *
@@ -1275,12 +1245,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_verify(psa_key_id_t key,
-                            psa_algorithm_t alg,
-                            const uint8_t *input,
-                            size_t input_length,
-                            const uint8_t *mac,
-                            size_t mac_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_mac_verify(psa_key_id_t key, psa_algorithm_t alg,
+						const uint8_t *input, size_t input_length,
+						const uint8_t *mac, size_t mac_length);
 
 /** The type of the state data structure for multipart MAC operations.
  *
@@ -1387,9 +1354,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
-                                psa_key_id_t key,
-                                psa_algorithm_t alg);
+PSA_CRYPTO_EXPORTED psa_status_t psa_mac_sign_setup(psa_mac_operation_t *operation,
+						    psa_key_id_t key, psa_algorithm_t alg);
 
 /** Set up a multipart MAC verification operation.
  *
@@ -1450,9 +1416,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
-                                  psa_key_id_t key,
-                                  psa_algorithm_t alg);
+PSA_CRYPTO_EXPORTED psa_status_t psa_mac_verify_setup(psa_mac_operation_t *operation,
+						      psa_key_id_t key, psa_algorithm_t alg);
 
 /** Add a message fragment to a multipart MAC operation.
  *
@@ -1481,9 +1446,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_update(psa_mac_operation_t *operation,
-                            const uint8_t *input,
-                            size_t input_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_mac_update(psa_mac_operation_t *operation,
+						const uint8_t *input, size_t input_length);
 
 /** Finish the calculation of the MAC of a message.
  *
@@ -1531,10 +1495,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation,
-                                 uint8_t *mac,
-                                 size_t mac_size,
-                                 size_t *mac_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_mac_sign_finish(psa_mac_operation_t *operation, uint8_t *mac,
+						     size_t mac_size, size_t *mac_length);
 
 /** Finish the calculation of the MAC of a message and compare it with
  * an expected value.
@@ -1575,9 +1537,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
-                                   const uint8_t *mac,
-                                   size_t mac_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_mac_verify_finish(psa_mac_operation_t *operation,
+						       const uint8_t *mac, size_t mac_length);
 
 /** Abort a MAC operation.
  *
@@ -1604,7 +1565,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_mac_abort(psa_mac_operation_t *operation);
+PSA_CRYPTO_EXPORTED psa_status_t psa_mac_abort(psa_mac_operation_t *operation);
 
 /**@}*/
 
@@ -1651,13 +1612,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_encrypt(psa_key_id_t key,
-                                psa_algorithm_t alg,
-                                const uint8_t *input,
-                                size_t input_length,
-                                uint8_t *output,
-                                size_t output_size,
-                                size_t *output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_encrypt(psa_key_id_t key, psa_algorithm_t alg,
+						    const uint8_t *input, size_t input_length,
+						    uint8_t *output, size_t output_size,
+						    size_t *output_length);
 
 /** Decrypt a message using a symmetric cipher.
  *
@@ -1698,13 +1656,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_decrypt(psa_key_id_t key,
-                                psa_algorithm_t alg,
-                                const uint8_t *input,
-                                size_t input_length,
-                                uint8_t *output,
-                                size_t output_size,
-                                size_t *output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_decrypt(psa_key_id_t key, psa_algorithm_t alg,
+						    const uint8_t *input, size_t input_length,
+						    uint8_t *output, size_t output_size,
+						    size_t *output_length);
 
 /** The type of the state data structure for multipart cipher operations.
  *
@@ -1812,9 +1767,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
-                                      psa_key_id_t key,
-                                      psa_algorithm_t alg);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_encrypt_setup(psa_cipher_operation_t *operation,
+							  psa_key_id_t key, psa_algorithm_t alg);
 
 /** Set the key for a multipart symmetric decryption operation.
  *
@@ -1876,9 +1830,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
-                                      psa_key_id_t key,
-                                      psa_algorithm_t alg);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_decrypt_setup(psa_cipher_operation_t *operation,
+							  psa_key_id_t key, psa_algorithm_t alg);
 
 /** Generate an IV for a symmetric encryption operation.
  *
@@ -1914,10 +1867,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
-                                    uint8_t *iv,
-                                    size_t iv_size,
-                                    size_t *iv_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_generate_iv(psa_cipher_operation_t *operation,
+							uint8_t *iv, size_t iv_size,
+							size_t *iv_length);
 
 /** Set the IV for a symmetric encryption or decryption operation.
  *
@@ -1956,9 +1908,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
-                               const uint8_t *iv,
-                               size_t iv_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_set_iv(psa_cipher_operation_t *operation,
+						   const uint8_t *iv, size_t iv_length);
 
 /** Encrypt or decrypt a message fragment in an active cipher operation.
  *
@@ -1998,12 +1949,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
-                               const uint8_t *input,
-                               size_t input_length,
-                               uint8_t *output,
-                               size_t output_size,
-                               size_t *output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_update(psa_cipher_operation_t *operation,
+						   const uint8_t *input, size_t input_length,
+						   uint8_t *output, size_t output_size,
+						   size_t *output_length);
 
 /** Finish encrypting or decrypting a message in a cipher operation.
  *
@@ -2051,10 +2000,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
-                               uint8_t *output,
-                               size_t output_size,
-                               size_t *output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_finish(psa_cipher_operation_t *operation,
+						   uint8_t *output, size_t output_size,
+						   size_t *output_length);
 
 /** Abort a cipher operation.
  *
@@ -2081,7 +2029,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation);
+PSA_CRYPTO_EXPORTED psa_status_t psa_cipher_abort(psa_cipher_operation_t *operation);
 
 /**@}*/
 
@@ -2139,17 +2087,13 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_encrypt(psa_key_id_t key,
-                              psa_algorithm_t alg,
-                              const uint8_t *nonce,
-                              size_t nonce_length,
-                              const uint8_t *additional_data,
-                              size_t additional_data_length,
-                              const uint8_t *plaintext,
-                              size_t plaintext_length,
-                              uint8_t *ciphertext,
-                              size_t ciphertext_size,
-                              size_t *ciphertext_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_encrypt(psa_key_id_t key, psa_algorithm_t alg,
+						  const uint8_t *nonce, size_t nonce_length,
+						  const uint8_t *additional_data,
+						  size_t additional_data_length,
+						  const uint8_t *plaintext, size_t plaintext_length,
+						  uint8_t *ciphertext, size_t ciphertext_size,
+						  size_t *ciphertext_length);
 
 /** Process an authenticated decryption operation.
  *
@@ -2201,17 +2145,13 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_decrypt(psa_key_id_t key,
-                              psa_algorithm_t alg,
-                              const uint8_t *nonce,
-                              size_t nonce_length,
-                              const uint8_t *additional_data,
-                              size_t additional_data_length,
-                              const uint8_t *ciphertext,
-                              size_t ciphertext_length,
-                              uint8_t *plaintext,
-                              size_t plaintext_size,
-                              size_t *plaintext_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_decrypt(psa_key_id_t key, psa_algorithm_t alg,
+						  const uint8_t *nonce, size_t nonce_length,
+						  const uint8_t *additional_data,
+						  size_t additional_data_length,
+						  const uint8_t *ciphertext,
+						  size_t ciphertext_length, uint8_t *plaintext,
+						  size_t plaintext_size, size_t *plaintext_length);
 
 /** The type of the state data structure for multipart AEAD operations.
  *
@@ -2325,9 +2265,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_id_t key,
-                                    psa_algorithm_t alg);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_encrypt_setup(psa_aead_operation_t *operation,
+							psa_key_id_t key, psa_algorithm_t alg);
 
 /** Set the key for a multipart authenticated decryption operation.
  *
@@ -2392,9 +2331,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
-                                    psa_key_id_t key,
-                                    psa_algorithm_t alg);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_decrypt_setup(psa_aead_operation_t *operation,
+							psa_key_id_t key, psa_algorithm_t alg);
 
 /** Generate a random nonce for an authenticated encryption operation.
  *
@@ -2432,10 +2370,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
-                                     uint8_t *nonce,
-                                     size_t nonce_size,
-                                     size_t *nonce_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_generate_nonce(psa_aead_operation_t *operation,
+							 uint8_t *nonce, size_t nonce_size,
+							 size_t *nonce_length);
 
 /** Set the nonce for an authenticated encryption or decryption operation.
  *
@@ -2473,9 +2410,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
-                                const uint8_t *nonce,
-                                size_t nonce_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_set_nonce(psa_aead_operation_t *operation,
+						    const uint8_t *nonce, size_t nonce_length);
 
 /** Declare the lengths of the message and additional data for AEAD.
  *
@@ -2519,9 +2455,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
-                                  size_t ad_length,
-                                  size_t plaintext_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_set_lengths(psa_aead_operation_t *operation,
+						      size_t ad_length, size_t plaintext_length);
 
 /** Pass additional data to an active AEAD operation.
  *
@@ -2568,9 +2503,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
-                                const uint8_t *input,
-                                size_t input_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_update_ad(psa_aead_operation_t *operation,
+						    const uint8_t *input, size_t input_length);
 
 /** Encrypt or decrypt a message fragment in an active AEAD operation.
  *
@@ -2646,12 +2580,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_update(psa_aead_operation_t *operation,
-                             const uint8_t *input,
-                             size_t input_length,
-                             uint8_t *output,
-                             size_t output_size,
-                             size_t *output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_update(psa_aead_operation_t *operation,
+						 const uint8_t *input, size_t input_length,
+						 uint8_t *output, size_t output_size,
+						 size_t *output_length);
 
 /** Finish encrypting a message in an AEAD operation.
  *
@@ -2722,13 +2654,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
-                             uint8_t *ciphertext,
-                             size_t ciphertext_size,
-                             size_t *ciphertext_length,
-                             uint8_t *tag,
-                             size_t tag_size,
-                             size_t *tag_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_finish(psa_aead_operation_t *operation,
+						 uint8_t *ciphertext, size_t ciphertext_size,
+						 size_t *ciphertext_length, uint8_t *tag,
+						 size_t tag_size, size_t *tag_length);
 
 /** Finish authenticating and decrypting a message in an AEAD operation.
  *
@@ -2802,12 +2731,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
-                             uint8_t *plaintext,
-                             size_t plaintext_size,
-                             size_t *plaintext_length,
-                             const uint8_t *tag,
-                             size_t tag_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_verify(psa_aead_operation_t *operation,
+						 uint8_t *plaintext, size_t plaintext_size,
+						 size_t *plaintext_length, const uint8_t *tag,
+						 size_t tag_length);
 
 /** Abort an AEAD operation.
  *
@@ -2834,7 +2761,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_aead_abort(psa_aead_operation_t *operation);
+PSA_CRYPTO_EXPORTED psa_status_t psa_aead_abort(psa_aead_operation_t *operation);
 
 /**@}*/
 
@@ -2900,13 +2827,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_sign_message(psa_key_id_t key,
-                              psa_algorithm_t alg,
-                              const uint8_t *input,
-                              size_t input_length,
-                              uint8_t *signature,
-                              size_t signature_size,
-                              size_t *signature_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_sign_message(psa_key_id_t key, psa_algorithm_t alg,
+						  const uint8_t *input, size_t input_length,
+						  uint8_t *signature, size_t signature_size,
+						  size_t *signature_length);
 
 /** \brief Verify the signature of a message with a public key, using
  *         a hash-and-sign verification algorithm.
@@ -2952,12 +2876,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_verify_message(psa_key_id_t key,
-                                psa_algorithm_t alg,
-                                const uint8_t *input,
-                                size_t input_length,
-                                const uint8_t * signature,
-                                size_t signature_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_verify_message(psa_key_id_t key, psa_algorithm_t alg,
+						    const uint8_t *input, size_t input_length,
+						    const uint8_t *signature,
+						    size_t signature_length);
 
 /**
  * \brief Sign a hash or short message with a private key.
@@ -3002,13 +2924,10 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_sign_hash(psa_key_id_t key,
-                           psa_algorithm_t alg,
-                           const uint8_t *hash,
-                           size_t hash_length,
-                           uint8_t *signature,
-                           size_t signature_size,
-                           size_t *signature_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_sign_hash(psa_key_id_t key, psa_algorithm_t alg,
+					       const uint8_t *hash, size_t hash_length,
+					       uint8_t *signature, size_t signature_size,
+					       size_t *signature_length);
 
 /**
  * \brief Verify the signature a hash or short message using a public key.
@@ -3050,12 +2969,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_verify_hash(psa_key_id_t key,
-                             psa_algorithm_t alg,
-                             const uint8_t *hash,
-                             size_t hash_length,
-                             const uint8_t *signature,
-                             size_t signature_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_verify_hash(psa_key_id_t key, psa_algorithm_t alg,
+						 const uint8_t *hash, size_t hash_length,
+						 const uint8_t *signature, size_t signature_length);
 
 /**
  * \brief Encrypt a short message with a public key.
@@ -3108,15 +3024,11 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_asymmetric_encrypt(psa_key_id_t key,
-                                    psa_algorithm_t alg,
-                                    const uint8_t *input,
-                                    size_t input_length,
-                                    const uint8_t *salt,
-                                    size_t salt_length,
-                                    uint8_t *output,
-                                    size_t output_size,
-                                    size_t *output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_asymmetric_encrypt(psa_key_id_t key, psa_algorithm_t alg,
+							const uint8_t *input, size_t input_length,
+							const uint8_t *salt, size_t salt_length,
+							uint8_t *output, size_t output_size,
+							size_t *output_length);
 
 /**
  * \brief Decrypt a short message with a private key.
@@ -3169,15 +3081,11 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_asymmetric_decrypt(psa_key_id_t key,
-                                    psa_algorithm_t alg,
-                                    const uint8_t *input,
-                                    size_t input_length,
-                                    const uint8_t *salt,
-                                    size_t salt_length,
-                                    uint8_t *output,
-                                    size_t output_size,
-                                    size_t *output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_asymmetric_decrypt(psa_key_id_t key, psa_algorithm_t alg,
+							const uint8_t *input, size_t input_length,
+							const uint8_t *salt, size_t salt_length,
+							uint8_t *output, size_t output_size,
+							size_t *output_length);
 
 /**@}*/
 
@@ -3291,9 +3199,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_setup(
-    psa_key_derivation_operation_t *operation,
-    psa_algorithm_t alg);
+PSA_CRYPTO_EXPORTED psa_status_t psa_key_derivation_setup(psa_key_derivation_operation_t *operation,
+							  psa_algorithm_t alg);
 
 /** Retrieve the current capacity of a key derivation operation.
  *
@@ -3315,9 +3222,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_get_capacity(
-    const psa_key_derivation_operation_t *operation,
-    size_t *capacity);
+PSA_CRYPTO_EXPORTED psa_status_t
+psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation, size_t *capacity);
 
 /** Set the maximum capacity of a key derivation operation.
  *
@@ -3344,9 +3250,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_set_capacity(
-    psa_key_derivation_operation_t *operation,
-    size_t capacity);
+PSA_CRYPTO_EXPORTED psa_status_t
+psa_key_derivation_set_capacity(psa_key_derivation_operation_t *operation, size_t capacity);
 
 /** Use the maximum possible capacity for a key derivation operation.
  *
@@ -3399,11 +3304,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_input_bytes(
-    psa_key_derivation_operation_t *operation,
-    psa_key_derivation_step_t step,
-    const uint8_t *data,
-    size_t data_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_key_derivation_input_bytes(
+	psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step,
+	const uint8_t *data, size_t data_length);
 
 /** Provide an input for key derivation in the form of a key.
  *
@@ -3452,10 +3355,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_input_key(
-    psa_key_derivation_operation_t *operation,
-    psa_key_derivation_step_t step,
-    psa_key_id_t key);
+PSA_CRYPTO_EXPORTED psa_status_t
+psa_key_derivation_input_key(psa_key_derivation_operation_t *operation,
+			     psa_key_derivation_step_t step, psa_key_id_t key);
 
 /** Perform a key agreement and use the shared secret as input to a key
  * derivation.
@@ -3522,12 +3424,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_key_agreement(
-    psa_key_derivation_operation_t *operation,
-    psa_key_derivation_step_t step,
-    psa_key_id_t private_key,
-    const uint8_t *peer_key,
-    size_t peer_key_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_key_derivation_key_agreement(
+	psa_key_derivation_operation_t *operation, psa_key_derivation_step_t step,
+	psa_key_id_t private_key, const uint8_t *peer_key, size_t peer_key_length);
 
 /** Read some data from a key derivation operation.
  *
@@ -3567,10 +3466,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_output_bytes(
-    psa_key_derivation_operation_t *operation,
-    uint8_t *output,
-    size_t output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_key_derivation_output_bytes(
+	psa_key_derivation_operation_t *operation, uint8_t *output, size_t output_length);
 
 /** Derive a key from an ongoing key derivation operation.
  *
@@ -3710,10 +3607,9 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_output_key(
-    const psa_key_attributes_t *attributes,
-    psa_key_derivation_operation_t *operation,
-    psa_key_id_t *key);
+PSA_CRYPTO_EXPORTED psa_status_t
+psa_key_derivation_output_key(const psa_key_attributes_t *attributes,
+			      psa_key_derivation_operation_t *operation, psa_key_id_t *key);
 
 /** Abort a key derivation operation.
  *
@@ -3738,8 +3634,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_key_derivation_abort(
-    psa_key_derivation_operation_t *operation);
+PSA_CRYPTO_EXPORTED psa_status_t psa_key_derivation_abort(psa_key_derivation_operation_t *operation);
 
 /** Perform a key agreement and return the raw shared secret.
  *
@@ -3792,13 +3687,11 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
-                                   psa_key_id_t private_key,
-                                   const uint8_t *peer_key,
-                                   size_t peer_key_length,
-                                   uint8_t *output,
-                                   size_t output_size,
-                                   size_t *output_length);
+PSA_CRYPTO_EXPORTED psa_status_t psa_raw_key_agreement(psa_algorithm_t alg,
+						       psa_key_id_t private_key,
+						       const uint8_t *peer_key,
+						       size_t peer_key_length, uint8_t *output,
+						       size_t output_size, size_t *output_length);
 
 /**@}*/
 
@@ -3830,8 +3723,7 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_generate_random(uint8_t *output,
-                                 size_t output_size);
+PSA_CRYPTO_EXPORTED psa_status_t psa_generate_random(uint8_t *output, size_t output_size);
 
 /**
  * \brief Generate a key or key pair.
@@ -3877,8 +3769,8 @@
  *         It is implementation-dependent whether a failure to initialize
  *         results in this error code.
  */
-psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
-                              psa_key_id_t *key);
+PSA_CRYPTO_EXPORTED psa_status_t psa_generate_key(const psa_key_attributes_t *attributes,
+						  psa_key_id_t *key);
 
 /**@}*/
 
@@ -3895,7 +3787,6 @@
  * implementation in TF-M. */
 #include "psa/crypto_client_struct.h"
 
-
 /* The file "crypto_struct.h" contains definitions for
  * implementation-specific structs that are declared above. */
 #include "psa/crypto_struct.h"
diff --git a/components/service/crypto/provider/crypto_provider.c b/components/service/crypto/provider/crypto_provider.c
index 9cd5208..f94b47e 100644
--- a/components/service/crypto/provider/crypto_provider.c
+++ b/components/service/crypto/provider/crypto_provider.c
@@ -3,16 +3,23 @@
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
+#include <protocols/common/efi/efi_status.h>
 #include <protocols/rpc/common/packed-c/status.h>
 #include <protocols/service/crypto/packed-c/opcodes.h>
 #include <service/crypto/backend/crypto_backend.h>
 #include <service/crypto/provider/crypto_provider.h>
+#include <compiler.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <string.h>
 
 #include "crypto_partition.h"
 #include "crypto_uuid.h"
 
+#if defined(MBEDTLS_PKCS7_C) && defined(MBEDTLS_X509_CRT_PARSE_C)
+#include "common/mbedtls/mbedtls_utils.h"
+#endif
+
 /* Service request handlers */
 static rpc_status_t generate_key_handler(void *context, struct rpc_request *req);
 static rpc_status_t destroy_key_handler(void *context, struct rpc_request *req);
@@ -28,25 +35,27 @@
 static rpc_status_t purge_key_handler(void *context, struct rpc_request *req);
 static rpc_status_t get_key_attributes_handler(void *context, struct rpc_request *req);
 static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_request *req);
+static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req);
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
-	{ TS_CRYPTO_OPCODE_GENERATE_KEY,           generate_key_handler },
-	{ TS_CRYPTO_OPCODE_DESTROY_KEY,            destroy_key_handler },
-	{ TS_CRYPTO_OPCODE_EXPORT_KEY,             export_key_handler },
-	{ TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY,      export_public_key_handler },
-	{ TS_CRYPTO_OPCODE_IMPORT_KEY,             import_key_handler },
-	{ TS_CRYPTO_OPCODE_SIGN_HASH,              asymmetric_sign_handler },
-	{ TS_CRYPTO_OPCODE_VERIFY_HASH,            asymmetric_verify_handler },
-	{ TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT,     asymmetric_decrypt_handler },
-	{ TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT,     asymmetric_encrypt_handler },
-	{ TS_CRYPTO_OPCODE_GENERATE_RANDOM,        generate_random_handler },
-	{ TS_CRYPTO_OPCODE_COPY_KEY,               copy_key_handler },
-	{ TS_CRYPTO_OPCODE_PURGE_KEY,              purge_key_handler },
-	{ TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES,     get_key_attributes_handler },
-	{ TS_CRYPTO_OPCODE_SIGN_MESSAGE,           asymmetric_sign_handler },
-	{ TS_CRYPTO_OPCODE_VERIFY_MESSAGE,         asymmetric_verify_handler },
-	{ TS_CRYPTO_OPCODE_VERIFY_PKCS7_SIGNATURE, verify_pkcs7_signature_handler },
+	{ TS_CRYPTO_OPCODE_GENERATE_KEY,            generate_key_handler },
+	{ TS_CRYPTO_OPCODE_DESTROY_KEY,             destroy_key_handler },
+	{ TS_CRYPTO_OPCODE_EXPORT_KEY,              export_key_handler },
+	{ TS_CRYPTO_OPCODE_EXPORT_PUBLIC_KEY,       export_public_key_handler },
+	{ TS_CRYPTO_OPCODE_IMPORT_KEY,              import_key_handler },
+	{ TS_CRYPTO_OPCODE_SIGN_HASH,               asymmetric_sign_handler },
+	{ TS_CRYPTO_OPCODE_VERIFY_HASH,             asymmetric_verify_handler },
+	{ TS_CRYPTO_OPCODE_ASYMMETRIC_DECRYPT,      asymmetric_decrypt_handler },
+	{ TS_CRYPTO_OPCODE_ASYMMETRIC_ENCRYPT,      asymmetric_encrypt_handler },
+	{ TS_CRYPTO_OPCODE_GENERATE_RANDOM,         generate_random_handler },
+	{ TS_CRYPTO_OPCODE_COPY_KEY,                copy_key_handler },
+	{ TS_CRYPTO_OPCODE_PURGE_KEY,               purge_key_handler },
+	{ TS_CRYPTO_OPCODE_GET_KEY_ATTRIBUTES,      get_key_attributes_handler },
+	{ TS_CRYPTO_OPCODE_SIGN_MESSAGE,            asymmetric_sign_handler },
+	{ TS_CRYPTO_OPCODE_VERIFY_MESSAGE,          asymmetric_verify_handler },
+	{ TS_CRYPTO_OPCODE_VERIFY_PKCS7_SIGNATURE,  verify_pkcs7_signature_handler },
+	{ TS_CRYPTO_OPCODE_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT, get_uefi_priv_auth_var_fingerprint_handler },
 };
 
 struct rpc_service_interface *
@@ -664,33 +673,44 @@
 	}
 
 	if (rpc_status == RPC_SUCCESS) {
-		/* Parse the public key certificate */
-		mbedtls_x509_crt signer_certificate;
+		/* Parse the PKCS#7 DER encoded signature block */
+		mbedtls_pkcs7 pkcs7_structure;
 
-		mbedtls_x509_crt_init(&signer_certificate);
+		mbedtls_pkcs7_init(&pkcs7_structure);
 
-		mbedtls_status = mbedtls_x509_crt_parse_der(&signer_certificate, public_key_cert,
-							    public_key_cert_len);
+		mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
+								signature_cert_len);
 
-		if (mbedtls_status == 0) {
-			/* Parse the PKCS#7 DER encoded signature block */
-			mbedtls_pkcs7 pkcs7_structure;
+		if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
 
-			mbedtls_pkcs7_init(&pkcs7_structure);
+			/*
+			 * If a separate public key is provided, verify the signature with it,
+			 * else use the key from the pkcs7 signature structure, because it is
+			 * a self-signed certificate.
+			 */
+			if(public_key_cert_len) {
+				/* Parse the public key certificate */
+				mbedtls_x509_crt signer_certificate;
 
-			mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
-								 signature_cert_len);
+				mbedtls_x509_crt_init(&signer_certificate);
 
-			if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
-				/* Verify hash against signed hash */
+				mbedtls_status = mbedtls_x509_crt_parse_der(&signer_certificate, public_key_cert,
+									public_key_cert_len);
+
+				if (mbedtls_status == 0) {
+					/* Verify hash against signed hash */
+					mbedtls_status = mbedtls_pkcs7_signed_hash_verify(
+						&pkcs7_structure, &signer_certificate, hash, hash_len);
+				}
+
+				mbedtls_x509_crt_free(&signer_certificate);
+			} else {
 				mbedtls_status = mbedtls_pkcs7_signed_hash_verify(
-					&pkcs7_structure, &signer_certificate, hash, hash_len);
+					&pkcs7_structure, &pkcs7_structure.private_signed_data.private_certs, hash, hash_len);
 			}
-
-			mbedtls_pkcs7_free(&pkcs7_structure);
 		}
 
-		mbedtls_x509_crt_free(&signer_certificate);
+		mbedtls_pkcs7_free(&pkcs7_structure);
 	}
 
 	free(signature_cert);
@@ -702,6 +722,111 @@
 
 	return rpc_status;
 }
+
+static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
+	const struct crypto_provider_serializer *serializer = get_crypto_serializer(context, req);
+
+	int mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+
+	uint8_t *signature_cert = NULL;
+	uint64_t signature_cert_len = 0;
+
+	if (serializer) {
+		/* First collect the lengths of the field */
+		rpc_status = serializer->deserialize_get_uefi_priv_auth_var_fingerprint_req(
+			req_buf, NULL, &signature_cert_len);
+
+		if (rpc_status == RPC_SUCCESS) {
+			/* Allocate the needed space and get the data */
+			signature_cert = (uint8_t *)malloc(signature_cert_len);
+
+			if (signature_cert) {
+				rpc_status = serializer->deserialize_get_uefi_priv_auth_var_fingerprint_req(
+					req_buf, signature_cert, &signature_cert_len);
+			} else {
+				rpc_status = RPC_ERROR_RESOURCE_FAILURE;
+			}
+		}
+	}
+
+	if (rpc_status == RPC_SUCCESS) {
+		/* Parse the PKCS#7 DER encoded signature block */
+		mbedtls_pkcs7 pkcs7_structure;
+
+		mbedtls_pkcs7_init(&pkcs7_structure);
+
+		mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
+								signature_cert_len);
+
+		if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
+
+			uint8_t output_buffer[PSA_HASH_MAX_SIZE] =  { 0 };
+			size_t __maybe_unused output_size = 0;
+			const mbedtls_asn1_buf *signerCertCN = NULL;
+			const mbedtls_x509_crt *topLevelCert = &pkcs7_structure.private_signed_data.private_certs;
+			const mbedtls_x509_buf *toplevelCertTbs = NULL;
+			struct rpc_buffer *resp_buf = &req->response;;
+			psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
+
+			/* Find common name field of the signing certificate, which is the first in the chain */
+			signerCertCN = findCommonName(&topLevelCert->subject);
+			if (!signerCertCN) {
+				mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+				goto end;
+			}
+
+			/* Get the TopLevel certificate which is the last in the chain */
+			while(topLevelCert->next)
+				topLevelCert = topLevelCert->next;
+			toplevelCertTbs = &topLevelCert->tbs;
+
+			/* Hash the data to create the fingerprint */
+			op = psa_hash_operation_init();
+
+			if (psa_hash_setup(&op, PSA_ALG_SHA_256) != PSA_SUCCESS) {
+				mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+				goto end;
+			}
+
+			if (psa_hash_update(&op, signerCertCN->p, signerCertCN->len)) {
+				psa_hash_abort(&op);
+				mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+				goto end;
+			}
+
+			if (psa_hash_update(&op, toplevelCertTbs->p, toplevelCertTbs->len)) {
+				psa_hash_abort(&op);
+				mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+				goto end;
+			}
+
+			if (psa_hash_finish(&op, (uint8_t*)&output_buffer, PSA_HASH_MAX_SIZE, &output_size)) {
+				psa_hash_abort(&op);
+				mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+				goto end;
+			}
+
+			/* Clear the remaining part of the buffer for consistency */
+			memset(&output_buffer[output_size], 0, PSA_HASH_MAX_SIZE - output_size);
+
+			rpc_status = serializer->serialize_get_uefi_priv_auth_var_fingerprint_resp(
+				resp_buf, (uint8_t*)&output_buffer);
+		}
+
+end:
+		mbedtls_pkcs7_free(&pkcs7_structure);
+	}
+
+	free(signature_cert);
+
+	/* Provide the result of the verification */
+	req->service_status = (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) ? EFI_SUCCESS : EFI_COMPROMISED_DATA;
+
+	return rpc_status;
+}
 #else
 static rpc_status_t verify_pkcs7_signature_handler(void *context, struct rpc_request *req)
 {
@@ -710,4 +835,12 @@
 
 	return RPC_ERROR_INTERNAL;
 }
+
+static rpc_status_t get_uefi_priv_auth_var_fingerprint_handler(void *context, struct rpc_request *req)
+{
+	(void)context;
+	(void)req;
+
+	return RPC_ERROR_INTERNAL;
+}
 #endif
diff --git a/components/service/crypto/provider/serializer/crypto_provider_serializer.h b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
index bd5336c..2b965af 100644
--- a/components/service/crypto/provider/serializer/crypto_provider_serializer.h
+++ b/components/service/crypto/provider/serializer/crypto_provider_serializer.h
@@ -126,6 +126,14 @@
 							       uint8_t *hash, uint64_t *hash_len,
 							       uint8_t *public_key_cert,
 							       uint64_t *public_key_cert_len);
+
+	/* Operation: get_uefi_priv_auth_var_fingerprintentifier */
+	rpc_status_t (*deserialize_get_uefi_priv_auth_var_fingerprint_req)(const struct rpc_buffer *req_buf,
+								uint8_t *signed_data,
+								uint64_t *signed_data_len);
+
+	rpc_status_t (*serialize_get_uefi_priv_auth_var_fingerprint_resp)(struct rpc_buffer *resp_buf,
+							       const uint8_t *output);
 };
 
 #endif /* CRYPTO_PROVIDER_SERIALIZER_H */
diff --git a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
index 050ef2f..89e07e2 100644
--- a/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
+++ b/components/service/crypto/provider/serializer/packed-c/packedc_crypto_provider_serializer.c
@@ -22,6 +22,7 @@
 #include <protocols/service/crypto/packed-c/sign_hash.h>
 #include <protocols/service/crypto/packed-c/verify_hash.h>
 #include <protocols/service/crypto/packed-c/verify_pkcs7_signature.h>
+#include <protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h>
 #include <service/crypto/backend/crypto_backend.h>
 #include <stdlib.h>
 #include <string.h>
@@ -675,6 +676,57 @@
 	return rpc_status;
 }
 
+/* Operation: get_uefi_priv_auth_var_fingerprintentifier */
+static rpc_status_t deserialize_get_uefi_priv_auth_var_fingerprint_req(const struct rpc_buffer *req_buf,
+							uint8_t *signed_data,
+							uint64_t *signed_data_len)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+
+	if (req_buf->data_length) {
+		struct tlv_const_iterator req_iter;
+		struct tlv_record decoded_record;
+
+		rpc_status = RPC_SUCCESS;
+
+		tlv_const_iterator_begin(&req_iter, (uint8_t *)req_buf->data, req_buf->data_length);
+
+		if (tlv_find_decode(&req_iter, TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_IN_TAG_SIGNATURE,
+				    &decoded_record)) {
+			*signed_data_len = decoded_record.length;
+
+			if (signed_data)
+				memcpy(signed_data, decoded_record.value, decoded_record.length);
+		} else {
+			/* Default to a zero length */
+			*signed_data_len = 0;
+		}
+	}
+
+	return rpc_status;
+}
+
+static rpc_status_t serialize_get_uefi_priv_auth_var_fingerprint_resp(struct rpc_buffer *resp_buf,
+							const uint8_t *output)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct tlv_iterator resp_iter;
+	struct tlv_record out_record;
+
+	out_record.tag = TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_OUT_TAG_IDENTIFIER;
+	out_record.length = PSA_HASH_MAX_SIZE;
+	out_record.value = output;
+
+	tlv_iterator_begin(&resp_iter, resp_buf->data, resp_buf->size);
+
+	if (tlv_encode(&resp_iter, &out_record)) {
+		resp_buf->data_length = tlv_required_space(PSA_HASH_MAX_SIZE);
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
 /* Singleton method to provide access to the serializer instance */
 const struct crypto_provider_serializer *packedc_crypto_provider_serializer_instance(void)
 {
@@ -704,6 +756,8 @@
 		deserialize_generate_random_req,
 		serialize_generate_random_resp,
 		deserialize_verify_pkcs7_signature_req,
+		deserialize_get_uefi_priv_auth_var_fingerprint_req,
+		serialize_get_uefi_priv_auth_var_fingerprint_resp
 	};
 
 	return &instance;
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.cpp b/components/service/crypto/test/service/crypto_service_scenarios.cpp
index db7d691..6f9fcda 100644
--- a/components/service/crypto/test/service/crypto_service_scenarios.cpp
+++ b/components/service/crypto/test/service/crypto_service_scenarios.cpp
@@ -10,6 +10,7 @@
 #include <vector>
 #include <CppUTest/TestHarness.h>
 #include "crypto_service_scenarios.h"
+#include "protocols/common/efi/efi_status.h"
 
 crypto_service_scenarios::crypto_service_scenarios(crypto_client *crypto_client) :
 	m_crypto_client(crypto_client)
@@ -774,4 +775,119 @@
 							 sizeof(public_key));
 
 	CHECK(status == 0);
-}
\ No newline at end of file
+}
+
+void crypto_service_scenarios::getUefiPrivAuthVarFingerprint(void)
+{
+	efi_status_t status = EFI_SUCCESS;
+
+	unsigned char certificate[] = {
+		0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+		0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+		0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01,
+		0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x5d, 0x64, 0x33, 0x8a, 0xce, 0x28, 0x15, 0x7f,
+		0x0f, 0x0f, 0x6c, 0xb2, 0xe2, 0x39, 0x97, 0x03, 0xd4, 0x91, 0xc2, 0x1b, 0x30, 0x0d, 0x06, 0x09,
+		0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30,
+		0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41, 0x52,
+		0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x35, 0x31, 0x33, 0x30, 0x39, 0x31, 0x39, 0x32, 0x30,
+		0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x35, 0x31, 0x31, 0x30, 0x39, 0x31, 0x39, 0x32, 0x30, 0x5a,
+		0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73,
+		0x74, 0x20, 0x56, 0x41, 0x52, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+		0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01,
+		0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbc, 0x46, 0x38, 0x19, 0x44, 0xc8, 0x9b, 0xf8, 0xaf, 0xc0,
+		0xdd, 0x1b, 0x09, 0x3a, 0x01, 0xa8, 0xab, 0x7b, 0x36, 0x8f, 0xcf, 0x69, 0xbf, 0x1e, 0x9e, 0xd0,
+		0x97, 0x3e, 0x77, 0xe2, 0xe9, 0x13, 0x13, 0xbc, 0x98, 0x7b, 0xea, 0x1f, 0xf0, 0x0a, 0x79, 0x62,
+		0xcc, 0x09, 0x58, 0x03, 0x3b, 0x33, 0x91, 0xa7, 0xcf, 0xb5, 0x1c, 0xa6, 0xc0, 0x92, 0x06, 0x96,
+		0xf1, 0x08, 0xcb, 0xbc, 0x8e, 0xee, 0xe2, 0x16, 0xf7, 0x8f, 0x73, 0x82, 0x23, 0x51, 0x8b, 0x6c,
+		0x0e, 0x7c, 0xad, 0x8c, 0x51, 0x4f, 0x50, 0x1d, 0x10, 0xf7, 0xcd, 0x28, 0xb7, 0x3f, 0x71, 0x4d,
+		0x65, 0xcc, 0x20, 0x42, 0x59, 0x66, 0xff, 0x13, 0xd2, 0xef, 0x0d, 0xe4, 0xbd, 0xe3, 0x9d, 0x4a,
+		0x90, 0x0b, 0xd1, 0xfb, 0x6c, 0xd4, 0x3c, 0x0e, 0x39, 0xee, 0x56, 0x6b, 0x16, 0xe8, 0xb0, 0xfe,
+		0xb3, 0xa7, 0xc2, 0x2c, 0x0a, 0xe9, 0x2f, 0xcb, 0x5c, 0x0d, 0x39, 0xd8, 0xeb, 0x00, 0x88, 0xa4,
+		0xea, 0xc6, 0x31, 0x3a, 0xd1, 0xa8, 0x2f, 0x05, 0x05, 0xae, 0xe5, 0x75, 0xb8, 0xc9, 0x0e, 0x45,
+		0x62, 0x89, 0xd7, 0x78, 0x7d, 0x51, 0x31, 0xae, 0x94, 0x91, 0x14, 0x75, 0xed, 0x6e, 0x1c, 0x9e,
+		0x51, 0x72, 0xe5, 0x76, 0x02, 0x77, 0x65, 0x15, 0xe9, 0x23, 0xd4, 0x1f, 0x27, 0x0b, 0x18, 0xff,
+		0xca, 0x9a, 0x44, 0x54, 0x8e, 0xcb, 0xf5, 0x80, 0xfe, 0x36, 0x96, 0x31, 0x70, 0x7e, 0x19, 0x3a,
+		0xc7, 0x0d, 0xc7, 0x81, 0x97, 0x61, 0x87, 0x5a, 0x60, 0x0b, 0x8c, 0xcf, 0x6e, 0x02, 0xc2, 0x61,
+		0x60, 0x25, 0x7b, 0x27, 0x21, 0x0d, 0x25, 0x82, 0x20, 0x52, 0xaa, 0x96, 0x8a, 0xd6, 0xe0, 0xc4,
+		0x5a, 0x2a, 0xa1, 0xd8, 0x9f, 0x4b, 0x86, 0x06, 0x85, 0xe2, 0x09, 0xad, 0x6d, 0x81, 0x12, 0x1c,
+		0x2a, 0x9c, 0xc3, 0x49, 0xdc, 0x7b, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+		0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x3f, 0xe5, 0x0f, 0xd8, 0x0d, 0x9c,
+		0x5f, 0x61, 0x4e, 0x39, 0x30, 0x75, 0x1f, 0x47, 0x8e, 0xef, 0x6f, 0xe4, 0xe6, 0x28, 0x30, 0x1f,
+		0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x3f, 0xe5, 0x0f, 0xd8, 0x0d,
+		0x9c, 0x5f, 0x61, 0x4e, 0x39, 0x30, 0x75, 0x1f, 0x47, 0x8e, 0xef, 0x6f, 0xe4, 0xe6, 0x28, 0x30,
+		0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff,
+		0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+		0x82, 0x01, 0x01, 0x00, 0x57, 0xb5, 0x65, 0x9e, 0x19, 0x88, 0x0a, 0x98, 0x92, 0xdd, 0x8c, 0x4b,
+		0x72, 0x2b, 0xf2, 0x3e, 0xe3, 0x9e, 0xcb, 0x06, 0x1f, 0xc3, 0x64, 0xc9, 0xdd, 0xf4, 0xb9, 0xa6,
+		0x25, 0x66, 0x00, 0xa1, 0x11, 0x98, 0x09, 0xcd, 0xf2, 0x82, 0x30, 0x03, 0xe6, 0xf6, 0x9d, 0x54,
+		0x38, 0x06, 0x75, 0x36, 0xce, 0x00, 0x7d, 0x7a, 0xb8, 0xb9, 0xbf, 0x9b, 0xa0, 0xd3, 0xa7, 0x59,
+		0x01, 0x21, 0xc4, 0x78, 0x6f, 0x5d, 0x72, 0xf2, 0xa2, 0x3a, 0xe9, 0xe9, 0xd0, 0xfb, 0x0e, 0xc1,
+		0x18, 0x37, 0x5b, 0x58, 0xa4, 0xc6, 0x0d, 0x0b, 0x42, 0xbb, 0x80, 0x8f, 0x64, 0xf5, 0x74, 0x22,
+		0x5a, 0xeb, 0x19, 0x52, 0xb5, 0x09, 0x06, 0x91, 0x13, 0x29, 0x41, 0x3d, 0x60, 0xfd, 0x1d, 0x95,
+		0x13, 0x7e, 0x49, 0xdc, 0x4b, 0x39, 0x3d, 0xda, 0x59, 0x85, 0xc1, 0xf7, 0xc1, 0x5a, 0x19, 0xc8,
+		0xf5, 0xdc, 0x6b, 0xf0, 0xa7, 0xcd, 0x1d, 0xd3, 0xbc, 0xf5, 0x51, 0x58, 0x86, 0x3a, 0x0a, 0x76,
+		0xc0, 0x30, 0x73, 0x3b, 0x8a, 0x89, 0x26, 0xfd, 0x36, 0x9a, 0xdb, 0x6f, 0x7b, 0x39, 0x16, 0x44,
+		0x41, 0xb9, 0x6e, 0xd6, 0x82, 0x05, 0xff, 0xf6, 0x9e, 0x51, 0xf4, 0x7d, 0xb5, 0x5b, 0xc1, 0x37,
+		0x16, 0xfa, 0x7f, 0x49, 0x69, 0xa1, 0x93, 0x9f, 0xd5, 0x55, 0x7b, 0xdf, 0xcc, 0xb1, 0x2c, 0xd3,
+		0xe7, 0x5a, 0x14, 0x95, 0x96, 0xc0, 0x73, 0x63, 0x65, 0xc8, 0x94, 0xe6, 0x16, 0xbb, 0x3e, 0x76,
+		0x56, 0xf9, 0x73, 0x23, 0x97, 0xb2, 0xb8, 0xae, 0xe0, 0x8c, 0x78, 0xd7, 0x42, 0x61, 0xbc, 0x07,
+		0x80, 0x40, 0x7e, 0xcd, 0x47, 0x90, 0x45, 0x9b, 0xba, 0x7a, 0xeb, 0xd2, 0xa8, 0x09, 0xfc, 0x38,
+		0xee, 0x0c, 0xe9, 0xf9, 0x40, 0x12, 0x36, 0xa7, 0xfd, 0xbf, 0xc8, 0xa3, 0x47, 0x99, 0x4a, 0x49,
+		0x49, 0x54, 0x11, 0x42, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30,
+		0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+		0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x02, 0x14, 0x5d, 0x64, 0x33, 0x8a, 0xce, 0x28, 0x15, 0x7f,
+		0x0f, 0x0f, 0x6c, 0xb2, 0xe2, 0x39, 0x97, 0x03, 0xd4, 0x91, 0xc2, 0x1b, 0x30, 0x0d, 0x06, 0x09,
+		0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+		0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x97, 0x77,
+		0x54, 0x3e, 0xdd, 0x8c, 0x08, 0xb9, 0x08, 0xa3, 0x49, 0x1a, 0x40, 0x85, 0x10, 0x41, 0x11, 0x8e,
+		0xb5, 0x55, 0xd5, 0x1c, 0x26, 0x48, 0x70, 0x7a, 0xa1, 0xd6, 0x9a, 0xb9, 0xdc, 0xcf, 0x94, 0x94,
+		0x5a, 0xc8, 0xc6, 0x9a, 0x9b, 0xe8, 0x6d, 0xce, 0x7c, 0x73, 0x57, 0x23, 0x29, 0x60, 0x43, 0x0c,
+		0x42, 0x6a, 0x60, 0x5b, 0xf0, 0x07, 0x30, 0x85, 0xe9, 0x03, 0x3f, 0x50, 0x3e, 0x42, 0xdd, 0xf6,
+		0xf6, 0x3a, 0xad, 0x01, 0xa4, 0x4b, 0x9b, 0xe2, 0xc3, 0xa0, 0xac, 0x9a, 0xa8, 0xbf, 0xcd, 0xff,
+		0xf2, 0xae, 0x7c, 0x0e, 0x10, 0xd2, 0x82, 0x72, 0xbb, 0x2b, 0x7e, 0x11, 0x70, 0x70, 0xac, 0x1a,
+		0x55, 0xf2, 0x75, 0xd8, 0x6b, 0xcc, 0xed, 0x8c, 0x56, 0xcc, 0xaf, 0x00, 0x4c, 0x40, 0x6a, 0xa5,
+		0x3b, 0xc3, 0xa2, 0x9e, 0x53, 0xb1, 0x69, 0xad, 0x25, 0x49, 0x0b, 0x95, 0x46, 0x69, 0xd0, 0x07,
+		0xc1, 0xb6, 0x08, 0x1b, 0xef, 0x7f, 0x72, 0x0c, 0xb3, 0xbb, 0x09, 0x64, 0x2c, 0xd4, 0xf9, 0x41,
+		0x8f, 0x09, 0x60, 0xfe, 0x08, 0x56, 0x1c, 0x6d, 0x31, 0xda, 0x48, 0xeb, 0xde, 0x2d, 0x4d, 0xb1,
+		0x53, 0x09, 0x7f, 0x23, 0x43, 0x9b, 0x78, 0xc1, 0x9c, 0x67, 0x71, 0xda, 0xf5, 0xa3, 0x84, 0xa8,
+		0x8c, 0xa6, 0x71, 0x62, 0x6c, 0x1f, 0x92, 0xff, 0xc7, 0x38, 0x39, 0x00, 0x50, 0x73, 0x8c, 0x68,
+		0x8a, 0x13, 0x47, 0xec, 0x0e, 0x3d, 0xef, 0xf5, 0xfb, 0xb0, 0xfc, 0x88, 0xe1, 0xdf, 0x48, 0x0f,
+		0xf2, 0x6b, 0x21, 0xb8, 0x2d, 0x13, 0x9f, 0x23, 0x54, 0x5d, 0x7e, 0xe3, 0xf0, 0xfb, 0x7a, 0x7e,
+		0x7b, 0x01, 0xdb, 0x3b, 0xda, 0x9f, 0x4a, 0xbe, 0xb7, 0xa1, 0x1e, 0x40, 0x57, 0x44, 0x12, 0x75,
+		0x97, 0xe7, 0xb8, 0x59, 0x57, 0x9e, 0x38, 0x4f, 0xfa, 0x20, 0x03, 0x2b, 0x11, 0xe2
+	};
+
+	unsigned char expected_fingerprint[PSA_HASH_MAX_SIZE] =
+	{
+		0x88, 0x46, 0xFC, 0x97, 0xDC, 0x48, 0x88, 0x71,
+		0xEB, 0x8A, 0x6A, 0x6A, 0xA2, 0x27, 0xF2, 0x90,
+		0x70, 0xA2, 0x51, 0xD4, 0x29, 0xF3, 0xE9, 0x7A,
+		0x18, 0x2D, 0x25, 0x59, 0x2A, 0x3C, 0x9A, 0xE5
+	};
+
+	unsigned char fingerprint[PSA_HASH_MAX_SIZE] = { 0 };
+
+	/* Inject error into the public key format and expect failure */
+	certificate[0] = ~certificate[0];
+	status = m_crypto_client->get_uefi_priv_auth_var_fingerprint((const uint8_t *)certificate,
+								     sizeof(certificate),
+								     (uint8_t *)&fingerprint);
+	certificate[0] = ~certificate[0];
+
+	CHECK(status != EFI_SUCCESS);
+
+	/* Try with wrong length */
+	status = m_crypto_client->get_uefi_priv_auth_var_fingerprint((const uint8_t *)certificate,
+								     sizeof(certificate) / 2,
+								     (uint8_t *)&fingerprint);
+
+	CHECK(status != EFI_SUCCESS);
+
+	/* Verify correct signature */
+	status = m_crypto_client->get_uefi_priv_auth_var_fingerprint((const uint8_t *)certificate,
+								     sizeof(certificate),
+								     (uint8_t *)&fingerprint);
+
+	CHECK(status == EFI_SUCCESS);
+	MEMCMP_EQUAL(expected_fingerprint, fingerprint, PSA_HASH_MAX_SIZE);
+}
diff --git a/components/service/crypto/test/service/crypto_service_scenarios.h b/components/service/crypto/test/service/crypto_service_scenarios.h
index 8081877..348c2c9 100644
--- a/components/service/crypto/test/service/crypto_service_scenarios.h
+++ b/components/service/crypto/test/service/crypto_service_scenarios.h
@@ -33,6 +33,7 @@
 	void copyKey();
 	void purgeKey();
 	void verifypkcs7signature(void);
+	void getUefiPrivAuthVarFingerprint(void);
 
 private:
 	crypto_client *m_crypto_client;
diff --git a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
index bc0f908..17a9b8a 100644
--- a/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
+++ b/components/service/crypto/test/service/packed-c/crypto_service_packedc_tests.cpp
@@ -117,3 +117,8 @@
 {
 	m_scenarios->verifypkcs7signature();
 }
+
+TEST(CryptoServicePackedcTests, getUefiPrivAuthVarFingerprint)
+{
+	m_scenarios->getUefiPrivAuthVarFingerprint();
+}
diff --git a/components/service/fwu/agent/fw_directory.c b/components/service/fwu/agent/fw_directory.c
index ec7486b..3e95cc0 100644
--- a/components/service/fwu/agent/fw_directory.c
+++ b/components/service/fwu/agent/fw_directory.c
@@ -11,7 +11,7 @@
 #include <stddef.h>
 #include <string.h>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 
 void fw_directory_init(struct fw_directory *fw_directory)
 {
diff --git a/components/service/fwu/agent/img_dir_serializer.c b/components/service/fwu/agent/img_dir_serializer.c
index d1f44af..e8dafea 100644
--- a/components/service/fwu/agent/img_dir_serializer.c
+++ b/components/service/fwu/agent/img_dir_serializer.c
@@ -11,7 +11,7 @@
 #include <string.h>
 
 #include "fw_directory.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
+#include "protocols/service/fwu/fwu_proto.h"
 #include "service/fwu/fw_store/fw_store.h"
 
 int img_dir_serializer_serialize(const struct fw_directory *fw_dir, const struct fw_store *fw_store,
@@ -24,7 +24,7 @@
 	if (buf_size < serialized_len)
 		return FWU_STATUS_OUT_OF_BOUNDS;
 
-	struct ts_fwu_image_directory *output = (struct ts_fwu_image_directory *)buf;
+	struct fwu_image_directory *output = (struct fwu_image_directory *)buf;
 
 	/* Clear the output buffer */
 	memset(buf, 0, serialized_len);
@@ -35,10 +35,10 @@
 	assert(boot_info);
 
 	output->directory_version = 2;
-	output->img_info_offset = offsetof(struct ts_fwu_image_directory, img_info_entry);
+	output->img_info_offset = offsetof(struct fwu_image_directory, img_info_entry);
 	output->num_images = fw_directory_num_images(fw_dir);
 	output->correct_boot = (boot_info->active_index == boot_info->boot_index);
-	output->img_info_size = sizeof(struct ts_fwu_image_info_entry);
+	output->img_info_size = sizeof(struct fwu_image_info_entry);
 	output->reserved = 0;
 
 	/* Serialize image info for each image */
@@ -67,6 +67,6 @@
 
 size_t img_dir_serializer_get_len(const struct fw_directory *fw_dir)
 {
-	return offsetof(struct ts_fwu_image_directory, img_info_entry) +
-	       sizeof(struct ts_fwu_image_info_entry) * fw_directory_num_images(fw_dir);
+	return offsetof(struct fwu_image_directory, img_info_entry) +
+	       sizeof(struct fwu_image_info_entry) * fw_directory_num_images(fw_dir);
 }
diff --git a/components/service/fwu/agent/stream_manager.c b/components/service/fwu/agent/stream_manager.c
index c93bdf1..bd7365f 100644
--- a/components/service/fwu/agent/stream_manager.c
+++ b/components/service/fwu/agent/stream_manager.c
@@ -9,7 +9,7 @@
 #include <stddef.h>
 #include <string.h>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/fw_store/fw_store.h"
 
 static uint32_t generate_handle(struct stream_manager *subject,
diff --git a/components/service/fwu/agent/update_agent.c b/components/service/fwu/agent/update_agent.c
index 2a4d19d..938361a 100644
--- a/components/service/fwu/agent/update_agent.c
+++ b/components/service/fwu/agent/update_agent.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -13,84 +13,67 @@
 
 #include "common/uuid/uuid.h"
 #include "img_dir_serializer.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/fw_store/fw_store.h"
 #include "service/fwu/inspector/fw_inspector.h"
+#include "trace.h"
 
-static bool open_image_directory(struct update_agent *update_agent, const struct uuid_octets *uuid,
-				 uint32_t *handle, int *status);
+/**
+ * \brief Update process states
+ *
+ * The update_agent is responsible for ensuring that only a valid update flow
+ * is followed by a client. To enforce the flow, public operations can only be
+ * used in a valid state that reflects the FWU-A behavioral model.
+ */
+enum fwu_state {
+	FWU_STATE_DEINITIALZED,
+	FWU_STATE_INITIALIZING,
+	FWU_STATE_REGULAR,
+	FWU_STATE_STAGING,
+	FWU_STATE_TRIAL_PENDING,
+	FWU_STATE_TRIAL
+};
 
-static bool open_fw_store_object(struct update_agent *update_agent, const struct uuid_octets *uuid,
-				 uint32_t *handle, int *status);
+/**
+ * \brief update_agent structure definition
+ *
+ * An update_agent instance is responsible for coordinating firmware updates applied
+ * to a fw_store. An update_agent performs a security role by enforcing that a
+ * valid flow is performed to update the fw store.
+ */
+struct generic_update_agent {
+	enum fwu_state state;
+	fw_inspector_inspect fw_inspect_method;
+	struct fw_store *fw_store;
+	struct fw_directory fw_directory;
+	struct stream_manager stream_manager;
+	uint8_t *image_dir_buf;
+	size_t image_dir_buf_size;
+};
 
-static bool open_fw_image(struct update_agent *update_agent, const struct uuid_octets *uuid,
-			  uint32_t *handle, int *status);
+static int cancel_staging(void *context);
 
-int update_agent_init(struct update_agent *update_agent, unsigned int boot_index,
-		      fw_inspector_inspect fw_inspect_method, struct fw_store *fw_store)
+static int discover(void *context, struct fwu_discovery_result *result)
 {
-	assert(update_agent);
-	assert(fw_inspect_method);
-	assert(fw_store);
-
-	int status = FWU_STATUS_UNKNOWN;
-
-	update_agent->state = FWU_STATE_INITIALIZING;
-	update_agent->fw_inspect_method = fw_inspect_method;
-	update_agent->fw_store = fw_store;
-	update_agent->image_dir_buf_size = 0;
-	update_agent->image_dir_buf = NULL;
-
-	stream_manager_init(&update_agent->stream_manager);
-
-	/* Initialize and populate the fw_directory. The fw_inspector will
-	 * obtain trustworthy information about the booted firmware and
-	 * populate the fw_directory to reflect information about the booted
-	 * firmware.
-	 */
-	fw_directory_init(&update_agent->fw_directory);
-
-	status = update_agent->fw_inspect_method(&update_agent->fw_directory, boot_index);
-	if (status != FWU_STATUS_SUCCESS)
-		return status;
-
-	/* Allow the associated fw_store to synchronize its state to the
-	 * state of the booted firmware reflected by the fw_directory.
-	 */
-	status = fw_store_synchronize(update_agent->fw_store, &update_agent->fw_directory,
-				      boot_index);
-	if (status != FWU_STATUS_SUCCESS)
-		return status;
-
-	/* Allocate a buffer for holding the serialized image directory  */
-	update_agent->image_dir_buf_size = img_dir_serializer_get_len(&update_agent->fw_directory);
-	update_agent->image_dir_buf = malloc(update_agent->image_dir_buf_size);
-	if (!update_agent->image_dir_buf)
-		return FWU_STATUS_UNKNOWN;
-
-	/* Transition to initial state */
-	update_agent->state = fw_store_is_trial(update_agent->fw_store) ? FWU_STATE_TRIAL :
-									  FWU_STATE_REGULAR;
+	result->service_status = 0;
+	result->version_major = FWU_PROTOCOL_VERSION_MAJOR;
+	result->version_minor = FWU_PROTOCOL_VERSION_MINOR;
+	result->max_payload_size = 0;
+	result->flags = 0;
+	result->vendor_specific_flags = 0;
 
 	return FWU_STATUS_SUCCESS;
 }
 
-void update_agent_deinit(struct update_agent *update_agent)
-{
-	update_agent->state = FWU_STATE_DEINITIALZED;
-
-	free(update_agent->image_dir_buf);
-	fw_directory_deinit(&update_agent->fw_directory);
-	stream_manager_deinit(&update_agent->stream_manager);
-}
-
-int update_agent_begin_staging(struct update_agent *update_agent)
+static int begin_staging(void *context, uint32_t vendor_flags, uint32_t partial_update_count,
+			 const struct uuid_octets *update_guid)
 {
 	int status = FWU_STATUS_DENIED;
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
 
 	/* If already staging, any previous installation state is discarded */
-	update_agent_cancel_staging(update_agent);
+	cancel_staging(update_agent);
 
 	if (update_agent->state == FWU_STATE_REGULAR) {
 		status = fw_store_begin_install(update_agent->fw_store);
@@ -103,9 +86,10 @@
 	return status;
 }
 
-int update_agent_end_staging(struct update_agent *update_agent)
+static int end_staging(void *context)
 {
 	int status = FWU_STATUS_DENIED;
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
 
 	if (update_agent->state == FWU_STATE_STAGING) {
 		/* The client is responsible for committing each installed image. If any
@@ -135,9 +119,10 @@
 	return status;
 }
 
-int update_agent_cancel_staging(struct update_agent *update_agent)
+static int cancel_staging(void *context)
 {
 	int status = FWU_STATUS_DENIED;
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
 
 	if (update_agent->state == FWU_STATE_STAGING) {
 		stream_manager_cancel_streams(&update_agent->stream_manager,
@@ -153,10 +138,10 @@
 	return status;
 }
 
-int update_agent_accept(struct update_agent *update_agent,
-			const struct uuid_octets *image_type_uuid)
+static int accept(void *context, const struct uuid_octets *image_type_uuid)
 {
 	int status = FWU_STATUS_DENIED;
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
 
 	if (update_agent->state == FWU_STATE_TRIAL) {
 		const struct image_info *image_info =
@@ -181,9 +166,10 @@
 	return status;
 }
 
-int update_agent_select_previous(struct update_agent *update_agent)
+static int select_previous(void *context)
 {
 	int status = FWU_STATUS_DENIED;
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
 
 	if ((update_agent->state == FWU_STATE_TRIAL) ||
 	    (update_agent->state == FWU_STATE_TRIAL_PENDING)) {
@@ -194,42 +180,8 @@
 	return status;
 }
 
-int update_agent_open(struct update_agent *update_agent, const struct uuid_octets *uuid,
-		      uint32_t *handle)
-{
-	int status;
-
-	/* Pass UUID along a chain-of-responsibility until it's handled */
-	if (!open_image_directory(update_agent, uuid, handle, &status) &&
-	    !open_fw_store_object(update_agent, uuid, handle, &status) &&
-	    !open_fw_image(update_agent, uuid, handle, &status)) {
-		/* UUID not recognised */
-		status = FWU_STATUS_UNKNOWN;
-	}
-
-	return status;
-}
-
-int update_agent_commit(struct update_agent *update_agent, uint32_t handle, bool accepted)
-{
-	return stream_manager_close(&update_agent->stream_manager, handle, accepted);
-}
-
-int update_agent_write_stream(struct update_agent *update_agent, uint32_t handle,
-			      const uint8_t *data, size_t data_len)
-{
-	return stream_manager_write(&update_agent->stream_manager, handle, data, data_len);
-}
-
-int update_agent_read_stream(struct update_agent *update_agent, uint32_t handle, uint8_t *buf,
-			     size_t buf_size, size_t *read_len, size_t *total_len)
-{
-	return stream_manager_read(&update_agent->stream_manager, handle, buf, buf_size, read_len,
-				   total_len);
-}
-
-static bool open_image_directory(struct update_agent *update_agent, const struct uuid_octets *uuid,
-				 uint32_t *handle, int *status)
+static bool open_image_directory(struct generic_update_agent *update_agent,
+				 const struct uuid_octets *uuid, uint32_t *handle, int *status)
 {
 	struct uuid_octets target_uuid;
 
@@ -257,8 +209,8 @@
 	return false;
 }
 
-static bool open_fw_store_object(struct update_agent *update_agent, const struct uuid_octets *uuid,
-				 uint32_t *handle, int *status)
+static bool open_fw_store_object(struct generic_update_agent *update_agent,
+				 const struct uuid_octets *uuid, uint32_t *handle, int *status)
 {
 	const uint8_t *exported_data;
 	size_t exported_data_len;
@@ -277,7 +229,7 @@
 	return false;
 }
 
-static bool open_fw_image(struct update_agent *update_agent, const struct uuid_octets *uuid,
+static bool open_fw_image(struct generic_update_agent *update_agent, const struct uuid_octets *uuid,
 			  uint32_t *handle, int *status)
 {
 	const struct image_info *image_info =
@@ -305,3 +257,160 @@
 
 	return false;
 }
+
+static int open(void *context, const struct uuid_octets *uuid, uint8_t op_type, uint32_t *handle)
+{
+	int status = FWU_STATUS_SUCCESS;
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
+
+	/* Pass UUID along a chain-of-responsibility until it's handled */
+	if (!open_image_directory(update_agent, uuid, handle, &status) &&
+	    !open_fw_store_object(update_agent, uuid, handle, &status) &&
+	    !open_fw_image(update_agent, uuid, handle, &status)) {
+		/* UUID not recognised */
+		status = FWU_STATUS_UNKNOWN;
+	}
+
+	return status;
+}
+
+static int commit(void *context, uint32_t handle, bool accepted, uint32_t max_atomic_len,
+		  uint32_t *progress, uint32_t *total_work)
+{
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
+	int result = 0;
+
+	result = stream_manager_close(&update_agent->stream_manager, handle, accepted);
+	if (!result)
+		*progress = 1;
+
+	*total_work = 1;
+
+	return result;
+}
+
+static int write_stream(void *context, uint32_t handle, const uint8_t *data, size_t data_len)
+{
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
+
+	return stream_manager_write(&update_agent->stream_manager, handle, data, data_len);
+}
+
+static int read_stream(void *context, uint32_t handle, uint8_t *buf, size_t buf_size,
+		       size_t *read_len, size_t *total_len)
+{
+	struct generic_update_agent *update_agent = (struct generic_update_agent *)context;
+
+	return stream_manager_read(&update_agent->stream_manager, handle, buf, buf_size, read_len,
+				   total_len);
+}
+
+
+static const struct update_agent_interface interface = {
+	.discover = discover,
+	.begin_staging = begin_staging,
+	.end_staging = end_staging,
+	.cancel_staging = cancel_staging,
+	.open = open,
+	.write_stream = write_stream,
+	.read_stream = read_stream,
+	.commit = commit,
+	.accept_image = accept,
+	.select_previous = select_previous,
+};
+
+static void deinit_context(struct generic_update_agent *context)
+{
+	if (!context)
+		return;
+
+	stream_manager_deinit(&context->stream_manager);
+	fw_directory_deinit(&context->fw_directory);
+
+	if (context->image_dir_buf)
+		free(context->image_dir_buf);
+
+	free(context);
+}
+
+struct update_agent *update_agent_init(unsigned int boot_index,
+				       fw_inspector_inspect fw_inspect_method,
+				       struct fw_store *fw_store)
+{
+	int status = FWU_STATUS_UNKNOWN;
+	struct generic_update_agent *context = NULL;
+	struct update_agent *agent = NULL;
+
+	assert(fw_inspect_method);
+	assert(fw_store);
+
+	context = (struct generic_update_agent *)calloc(1, sizeof(*context));
+	if (!context) {
+		DMSG("Failed to allocate update agent context");
+		return NULL;
+	}
+
+	context->state = FWU_STATE_INITIALIZING;
+	context->fw_inspect_method = fw_inspect_method;
+	context->fw_store = fw_store;
+	context->image_dir_buf_size = 0;
+	context->image_dir_buf = NULL;
+
+	stream_manager_init(&context->stream_manager);
+
+	/* Initialize and populate the fw_directory. The fw_inspector will
+	 * obtain trustworthy information about the booted firmware and
+	 * populate the fw_directory to reflect information about the booted
+	 * firmware.
+	 */
+	fw_directory_init(&context->fw_directory);
+
+	status = context->fw_inspect_method(&context->fw_directory, boot_index);
+	if (status != FWU_STATUS_SUCCESS) {
+		DMSG("Failed to run FW inspect: %d", status);
+		deinit_context(context);
+		return NULL;
+	}
+
+	/* Allow the associated fw_store to synchronize its state to the
+	 * state of the booted firmware reflected by the fw_directory.
+	 */
+	status = fw_store_synchronize(context->fw_store, &context->fw_directory, boot_index);
+	if (status != FWU_STATUS_SUCCESS) {
+		DMSG("Failed synchronize FW store: %d", status);
+		deinit_context(context);
+		return NULL;
+	}
+
+	/* Allocate a buffer for holding the serialized image directory  */
+	context->image_dir_buf_size = img_dir_serializer_get_len(&context->fw_directory);
+	context->image_dir_buf = malloc(context->image_dir_buf_size);
+	if (!context->image_dir_buf) {
+		DMSG("Failed to allocate image_dir_buf");
+		deinit_context(context);
+		return NULL;
+	}
+
+	/* Transition to initial state */
+	context->state = fw_store_is_trial(context->fw_store) ? FWU_STATE_TRIAL : FWU_STATE_REGULAR;
+
+	agent = (struct update_agent *)calloc(1, sizeof(*agent));
+	if (!agent) {
+		DMSG("Failed to allocate update_agent");
+		deinit_context(context);
+		return NULL;
+	}
+
+	agent->context = context;
+	agent->interface = &interface;
+
+	return agent;
+}
+
+void update_agent_deinit(struct update_agent *update_agent)
+{
+	struct generic_update_agent *context = (struct generic_update_agent *)update_agent->context;
+
+	deinit_context(context);
+	free(update_agent);
+}
diff --git a/components/service/fwu/agent/update_agent.h b/components/service/fwu/agent/update_agent.h
index ea214ee..9004252 100644
--- a/components/service/fwu/agent/update_agent.h
+++ b/components/service/fwu/agent/update_agent.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -15,6 +15,7 @@
 #include "fw_directory.h"
 #include "service/fwu/inspector/fw_inspector.h"
 #include "stream_manager.h"
+#include "components/service/fwu/common/update_agent_interface.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -26,39 +27,6 @@
 struct fw_store;
 
 /**
- * \brief Update process states
- *
- * The update_agent is responsible for ensuring that only a valid update flow
- * is followed by a client. To enforce the flow, public operations can only be
- * used in a valid state that reflects the FWU-A behavioral model.
- */
-enum fwu_state {
-	FWU_STATE_DEINITIALZED,
-	FWU_STATE_INITIALIZING,
-	FWU_STATE_REGULAR,
-	FWU_STATE_STAGING,
-	FWU_STATE_TRIAL_PENDING,
-	FWU_STATE_TRIAL
-};
-
-/**
- * \brief update_agent structure definition
- *
- * An update_agent instance is responsible for coordinating firmware updates applied
- * to a fw_store. An update_agent performs a security role by enforcing that a
- * valid flow is performed to update the fw store.
- */
-struct update_agent {
-	enum fwu_state state;
-	fw_inspector_inspect fw_inspect_method;
-	struct fw_store *fw_store;
-	struct fw_directory fw_directory;
-	struct stream_manager stream_manager;
-	uint8_t *image_dir_buf;
-	size_t image_dir_buf_size;
-};
-
-/**
  * \brief Initialise the update_agent
  *
  * \param[in]  update_agent    The subject update_agent
@@ -66,10 +34,11 @@
  * \param[in]  fw_inspect_method  fw_inspector inspect method
  * \param[in]  fw_store        The fw_store to manage
  *
- * \return Status (0 for success).  Uses fwu protocol status codes.
+ * \return Update agent instance or NULL on error
  */
-int update_agent_init(struct update_agent *update_agent, unsigned int boot_index,
-		      fw_inspector_inspect fw_inspect_method, struct fw_store *fw_store);
+struct update_agent *update_agent_init(unsigned int boot_index,
+				       fw_inspector_inspect fw_inspect_method,
+				       struct fw_store *fw_store);
 
 /**
  * \brief De-initialise the update_agent
@@ -78,109 +47,6 @@
  */
 void update_agent_deinit(struct update_agent *update_agent);
 
-/**
- * \brief Begin staging
- *
- * \param[in]  update_agent    The subject update_agent
- *
- * \return 0 on successfully transitioning to the STAGING state
- */
-int update_agent_begin_staging(struct update_agent *update_agent);
-
-/**
- * \brief End staging
- *
- * \param[in]  update_agent    The subject update_agent
- *
- * \return 0 on successfully transitioning to the TRIAL state
- */
-int update_agent_end_staging(struct update_agent *update_agent);
-
-/**
- * \brief Cancel staging
- *
- * \param[in]  update_agent    The subject update_agent
- *
- * \return 0 on successfully transitioning to the REGULAR state
- */
-int update_agent_cancel_staging(struct update_agent *update_agent);
-
-/**
- * \brief Accept an updated image
- *
- * \param[in]  update_agent    The subject update_agent
- * \param[in]  image_type_uuid Identifies the image to accept
- *
- * \return Status (0 on success)
- */
-int update_agent_accept(struct update_agent *update_agent,
-			const struct uuid_octets *image_type_uuid);
-
-/**
- * \brief Select previous version
- *
- *  Revert to a previous good version (if possible).
- *
- * \param[in]  update_agent    The subject update_agent
- *
- * \return Status (0 on success)
- */
-int update_agent_select_previous(struct update_agent *update_agent);
-
-/**
- * \brief Open a stream for accessing an fwu stream
- *
- * Used for reading or writing data for accessing images or other fwu
- * related objects.
- *
- * \param[in]  update_agent    The subject update_agent
- * \param[in]  uuid            Identifies the object to access
- * \param[out] handle          For subsequent read/write operations
- *
- * \return Status (0 on success)
- */
-int update_agent_open(struct update_agent *update_agent, const struct uuid_octets *uuid,
-		      uint32_t *handle);
-
-/**
- * \brief Close a stream and commit any writes to the stream
- *
- * \param[in]  update_agent    The subject update_agent
- * \param[in]  handle          The handle returned by open
- * \param[in]  accepted        Initial accepted state of an image
- *
- * \return Status (0 on success)
- */
-int update_agent_commit(struct update_agent *update_agent, uint32_t handle, bool accepted);
-
-/**
- * \brief Write to a previously opened stream
- *
- * \param[in]  update_agent    The subject update_agent
- * \param[in]  handle          The handle returned by open
- * \param[in]  data            Pointer to data
- * \param[in]  data_len        The data length
- *
- * \return Status (0 on success)
- */
-int update_agent_write_stream(struct update_agent *update_agent, uint32_t handle,
-			      const uint8_t *data, size_t data_len);
-
-/**
- * \brief Read from a previously opened stream
- *
- * \param[in]  update_agent    The subject update_agent
- * \param[in]  handle          The handle returned by open
- * \param[in]  buf             Pointer to buffer to copy to
- * \param[in]  buf_size        The size of the buffer
- * \param[out] read_len        The length of data read
- * \param[out] total_len       The total length of the object to read
- *
- * \return Status (0 on success)
- */
-int update_agent_read_stream(struct update_agent *update_agent, uint32_t handle, uint8_t *buf,
-			     size_t buf_size, size_t *read_len, size_t *total_len);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/service/fwu/common/component.cmake
similarity index 72%
copy from components/service/fwu/provider/serializer/packed-c/component.cmake
copy to components/service/fwu/common/component.cmake
index 4209cae..156f230 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/service/fwu/common/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
-	)
+	"${CMAKE_CURRENT_LIST_DIR}/update_agent_interface.c"
+)
diff --git a/components/service/fwu/common/update_agent_interface.c b/components/service/fwu/common/update_agent_interface.c
new file mode 100644
index 0000000..0582036
--- /dev/null
+++ b/components/service/fwu/common/update_agent_interface.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "update_agent_interface.h"
+#include "protocols/service/fwu/status.h"
+
+int update_agent_discover(struct update_agent *update_agent, struct fwu_discovery_result *result)
+{
+	if (!update_agent->interface->discover)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->discover(update_agent->context, result);
+}
+
+int update_agent_begin_staging(struct update_agent *update_agent, uint32_t vendor_flags,
+			       uint32_t partial_update_count,
+			       const struct uuid_octets *update_guid)
+{
+	if (!update_agent->interface->begin_staging)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->begin_staging(update_agent->context, vendor_flags,
+						      partial_update_count, update_guid);
+}
+
+int update_agent_end_staging(struct update_agent *update_agent)
+{
+	if (!update_agent->interface->end_staging)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->end_staging(update_agent->context);
+}
+
+int update_agent_cancel_staging(struct update_agent *update_agent)
+{
+	if (!update_agent->interface->cancel_staging)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->cancel_staging(update_agent->context);
+}
+
+int update_agent_open(struct update_agent *update_agent, const struct uuid_octets *uuid,
+		      uint8_t op_type, uint32_t *handle)
+{
+	if (!update_agent->interface->open)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->open(update_agent->context, uuid, op_type, handle);
+}
+
+int update_agent_write_stream(struct update_agent *update_agent, uint32_t handle,
+			      const uint8_t *data, size_t data_len)
+{
+	if (!update_agent->interface->write_stream)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->write_stream(update_agent->context, handle, data, data_len);
+}
+
+int update_agent_read_stream(struct update_agent *update_agent, uint32_t handle, uint8_t *buf,
+			     size_t buf_size, size_t *read_len, size_t *total_len)
+{
+	if (!update_agent->interface->read_stream)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->read_stream(update_agent->context, handle, buf, buf_size,
+						    read_len, total_len);
+}
+
+int update_agent_commit(struct update_agent *update_agent, uint32_t handle, bool accepted,
+			uint32_t max_atomic_len, uint32_t *progress, uint32_t *total_work)
+{
+	if (!update_agent->interface->commit)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->commit(update_agent->context, handle, accepted,
+					       max_atomic_len, progress, total_work);
+}
+
+int update_agent_accept_image(struct update_agent *update_agent,
+			      const struct uuid_octets *image_type_uuid)
+{
+	if (!update_agent->interface->accept_image)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->accept_image(update_agent->context, image_type_uuid);
+}
+
+int update_agent_select_previous(struct update_agent *update_agent)
+{
+	if (!update_agent->interface->select_previous)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return update_agent->interface->select_previous(update_agent->context);
+}
diff --git a/components/service/fwu/common/update_agent_interface.h b/components/service/fwu/common/update_agent_interface.h
new file mode 100644
index 0000000..8681672
--- /dev/null
+++ b/components/service/fwu/common/update_agent_interface.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef UPDATE_AGENT_INTERFACE_H
+#define UPDATE_AGENT_INTERFACE_H
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include "common/uuid/uuid.h"
+#include "protocols/service/fwu/status.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FWU_OP_TYPE_READ	(0)
+#define FWU_OP_TYPE_WRITE	(1)
+
+#define FWU_FLAG_PARTIAL_UPDATE	(0x01)
+
+struct fwu_discovery_result {
+	int16_t service_status;
+	uint8_t version_major;
+	uint8_t version_minor;
+	uint64_t max_payload_size;
+	uint32_t flags;
+	uint32_t vendor_specific_flags;
+};
+
+struct update_agent_interface {
+	/**
+	 * \brief Discovery
+	 *
+	 * \param[in]  context         The update_agent context
+	 * \param[out] result          Discovery result structure
+	 *
+	 * \return 0 on success
+	 */
+	int (*discover)(void *context, struct fwu_discovery_result *result);
+
+	/**
+	 * \brief Begin staging
+	 *
+	 * \param[in]  context         The update_agent context
+	 * \param[in]  vendor_flags    Vendor specific staging flags
+	 * \param[in]  partial_update_count     Number of update_guid elements
+	 * \param[in]  update_guid     Images to update
+	 *
+	 *
+	 * \return 0 on successfully transitioning to the STAGING state
+	 */
+	int (*begin_staging)(void *context, uint32_t vendor_flags, uint32_t partial_update_count,
+			     const struct uuid_octets *update_guid);
+
+	/**
+	 * \brief End staging
+	 *
+	 * \param[in]  context         The update_agent context
+	 *
+	 * \return 0 on successfully transitioning to the TRIAL state
+	 */
+	int (*end_staging)(void *context);
+
+	/**
+	 * \brief Cancel staging
+	 *
+	 * \param[in]  context         The update_agent context
+	 *
+	 * \return 0 on successfully transitioning to the REGULAR state
+	 */
+	int (*cancel_staging)(void *context);
+
+	/**
+	 * \brief Open a stream for accessing an fwu stream
+	 *
+	 * Used for reading or writing data for accessing images or other fwu
+	 * related objects.
+	 *
+	 * \param[in]  context         The update_agent context
+	 * \param[in]  uuid            Identifies the object to access
+	 * \param[in]  op_type         Read/write operation, use FWU_OP_TYPE_* macros
+	 * \param[out] handle          For subsequent read/write operations
+	 *
+	 * \return 0 on success
+	 */
+	int (*open)(void *context, const struct uuid_octets *uuid, uint8_t op_type,
+		    uint32_t *handle);
+
+	/**
+	 * \brief Write to a previously opened stream
+	 *
+	 * \param[in]  context         The update_agent context
+	 * \param[in]  handle          The handle returned by open
+	 * \param[in]  data            Pointer to data
+	 * \param[in]  data_len        The data length
+	 *
+	 * \return 0 on success
+	 */
+	int (*write_stream)(void *context, uint32_t handle, const uint8_t *data, size_t data_len);
+
+	/**
+	 * \brief Read from a previously opened stream
+	 *
+	 * \param[in]  context         The update_agent context
+	 * \param[in]  handle          The handle returned by open
+	 * \param[in]  buf             Pointer to buffer to copy to
+	 * \param[in]  buf_size        The size of the buffer
+	 * \param[out] read_len        The length of data read
+	 * \param[out] total_len       The total length of the object to read
+	 *
+	 * \return 0 on success
+	 */
+	int (*read_stream)(void *context, uint32_t handle, uint8_t *buf, size_t buf_size,
+			   size_t *read_len, size_t *total_len);
+
+	/**
+	 * \brief Close a stream and commit any writes to the stream
+	 *
+	 * \param[in]  context         The update_agent context
+	 * \param[in]  handle          The handle returned by open
+	 * \param[in]  accepted        Initial accepted state of an image
+	 * \param[in]  max_atomic_len  Hint, maximum time (in ns) that the Update Agent can execute
+	 *                             continuously without yielding back to the Client. A value of
+	 *                             0 means that the Update Agent can execute for an unbounded
+	 *                             time.
+	 * \param[in]  progress        Units of work already completed by the Update Agent
+	 * \param[in]  total_work      Units of work the Update Agent must perform until fwu_commit
+	 *                             returns successfully
+	 *
+	 * \return 0 on success
+	 */
+	int (*commit)(void *context, uint32_t handle, bool accepted, uint32_t max_atomic_len, uint32_t *progress,
+		      uint32_t *total_work);
+
+
+	/**
+	 * \brief Accept an updated image
+	 *
+	 * \param[in]  context         The update_agent context
+	 * \param[in]  image_type_uuid Identifies the image to accept
+	 *
+	 * \return 0 on success
+	 */
+	int (*accept_image)(void *context, const struct uuid_octets *image_type_uuid);
+
+	/**
+	 * \brief Select previous version
+	 *
+	 *  Revert to a previous good version (if possible).
+	 *
+	 * \param[in]  context         The update_agent context
+	 *
+	 * \return 0 on success
+	 */
+	int (*select_previous)(void *context);
+};
+
+/**
+ * \brief Common update agent instance
+ *
+ * Used by the FWU provider make an association with an agent.
+ */
+struct update_agent {
+	/**
+	 * \brief The update_agent context
+	 *
+	 * Points to backend specific instance data.
+	 */
+	void *context;
+
+	/**
+	 * \brief The update agent interface
+	 *
+	 * A concrete agent provides an implementation of this interface.
+	 */
+	const struct update_agent_interface *interface;
+};
+
+int update_agent_discover(struct update_agent *update_agent, struct fwu_discovery_result *result);
+
+int update_agent_begin_staging(struct update_agent *update_agent, uint32_t vendor_flags,
+			       uint32_t partial_update_count,
+			       const struct uuid_octets *update_guid);
+
+int update_agent_end_staging(struct update_agent *update_agent);
+
+int update_agent_cancel_staging(struct update_agent *update_agent);
+
+int update_agent_open(struct update_agent *update_agent, const struct uuid_octets *uuid,
+		      uint8_t op_type, uint32_t *handle);
+
+int update_agent_write_stream(struct update_agent *update_agent, uint32_t handle,
+			      const uint8_t *data, size_t data_len);
+
+int update_agent_read_stream(struct update_agent *update_agent, uint32_t handle, uint8_t *buf,
+			     size_t buf_size, size_t *read_len, size_t *total_len);
+
+int update_agent_commit(struct update_agent *update_agent, uint32_t handle, bool accepted,
+			uint32_t max_atomic_len, uint32_t *progress, uint32_t *total_work);
+
+int update_agent_accept_image(struct update_agent *update_agent,
+			      const struct uuid_octets *image_type_uuid);
+
+int update_agent_select_previous(struct update_agent *update_agent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UPDATE_AGENT_INTERFACE_H */
diff --git a/components/service/fwu/fw_store/banked/banked_fw_store.c b/components/service/fwu/fw_store/banked/banked_fw_store.c
index b987b48..e88095f 100644
--- a/components/service/fwu/fw_store/banked/banked_fw_store.c
+++ b/components/service/fwu/fw_store/banked/banked_fw_store.c
@@ -13,8 +13,8 @@
 
 #include "bank_scheme.h"
 #include "common/uuid/uuid.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/installer/installer.h"
 #include "service/fwu/installer/installer_index.h"
 #include "volume_id.h"
diff --git a/components/service/fwu/fw_store/banked/metadata_manager.c b/components/service/fwu/fw_store/banked/metadata_manager.c
index 954dcc9..fe6eb66 100644
--- a/components/service/fwu/fw_store/banked/metadata_manager.c
+++ b/components/service/fwu/fw_store/banked/metadata_manager.c
@@ -15,7 +15,7 @@
 #include "common/crc32/crc32.h"
 #include "media/volume/index/volume_index.h"
 #include "media/volume/volume.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/fw_store/banked/metadata_serializer/metadata_serializer.h"
 #include "trace.h"
 #include "volume_id.h"
diff --git a/components/service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.c b/components/service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.c
index 5458b4c..4e2a3dd 100644
--- a/components/service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.c
+++ b/components/service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.c
@@ -14,8 +14,8 @@
 #include "common/uuid/uuid.h"
 #include "media/volume/index/volume_index.h"
 #include "media/volume/volume.h"
-#include "protocols/service/fwu/packed-c/metadata_v1.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/metadata_v1.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/agent/fw_directory.h"
 #include "service/fwu/fw_store/banked/bank_tracker.h"
 #include "service/fwu/fw_store/banked/metadata_serializer/metadata_serializer.h"
diff --git a/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.c b/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.c
index 1ef61e4..b8a4012 100644
--- a/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.c
+++ b/components/service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -14,8 +14,8 @@
 #include "common/uuid/uuid.h"
 #include "media/volume/index/volume_index.h"
 #include "media/volume/volume.h"
-#include "protocols/service/fwu/packed-c/metadata_v2.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/metadata_v2.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/agent/fw_directory.h"
 #include "service/fwu/fw_store/banked/bank_tracker.h"
 #include "service/fwu/fw_store/banked/metadata_serializer/metadata_serializer.h"
@@ -104,7 +104,7 @@
 	fw_store_desc->num_banks = BANK_SCHEME_NUM_BANKS;
 	fw_store_desc->num_images = fw_directory_num_images(fw_dir);
 	fw_store_desc->img_entry_size = sizeof(struct fwu_image_entry);
-	fw_store_desc->bank_entry_size = sizeof(struct fwu_img_bank_info);
+	fw_store_desc->bank_info_entry_size = sizeof(struct fwu_img_bank_info);
 
 	return serialize_image_entries(fw_store_desc, fw_dir, bank_tracker);
 }
@@ -126,7 +126,7 @@
 		metadata->crc_32 = 0;
 		metadata->version = 2;
 		metadata->metadata_size = (uint32_t)serialized_size;
-		metadata->header_size = (uint16_t)sizeof(struct fwu_metadata);
+		metadata->descriptor_offset = (uint16_t)sizeof(struct fwu_metadata);
 		metadata->active_index = active_index;
 		metadata->previous_active_index = previous_active_index;
 
@@ -150,9 +150,9 @@
 		}
 
 		/* Serialize optional fw store descriptor if required */
-		if (serialized_size > metadata->header_size)
+		if (serialized_size > metadata->descriptor_offset)
 			status = serialize_fw_store_desc(fw_dir, bank_tracker,
-							 &buf[metadata->header_size]);
+							 &buf[metadata->descriptor_offset]);
 		else
 			status = FWU_STATUS_SUCCESS;
 
@@ -170,7 +170,8 @@
 	const struct fwu_metadata *metadata = (const struct fwu_metadata *)serialized_metadata;
 
 	/* Sanity check size values in header */
-	if ((metadata->header_size > metadata_len) || (metadata->metadata_size > metadata_len))
+	if ((metadata->descriptor_offset > metadata_len) ||
+	    (metadata->metadata_size > metadata_len))
 		return;
 
 	/* Deserialize bank state in header and update bank_tracker to reflect the same state */
@@ -183,20 +184,20 @@
 
 	/* If present, deserialize the fw_store_desc */
 	if (metadata->metadata_size >=
-	    metadata->header_size + offsetof(struct fwu_fw_store_desc, img_entry)) {
+	    metadata->descriptor_offset + offsetof(struct fwu_fw_store_desc, img_entry)) {
 		const struct fwu_fw_store_desc *fw_store_desc =
 			(const struct fwu_fw_store_desc *)(serialized_metadata +
-							   metadata->header_size);
+							   metadata->descriptor_offset);
 
-		size_t fw_store_desc_size = metadata->metadata_size - metadata->header_size;
+		size_t fw_store_desc_size = metadata->metadata_size - metadata->descriptor_offset;
 		size_t total_img_entries_size =
 			fw_store_desc_size - offsetof(struct fwu_fw_store_desc, img_entry);
 		size_t per_img_entry_bank_info_size =
-			fw_store_desc->num_banks * fw_store_desc->bank_entry_size;
+			fw_store_desc->num_banks * fw_store_desc->bank_info_entry_size;
 
 		/* Sanity check fw_store_desc values */
 		if ((fw_store_desc->img_entry_size < sizeof(struct fwu_image_entry)) ||
-		    (fw_store_desc->bank_entry_size < sizeof(struct fwu_img_bank_info)) ||
+		    (fw_store_desc->bank_info_entry_size < sizeof(struct fwu_img_bank_info)) ||
 		    (fw_store_desc->num_banks > BANK_SCHEME_NUM_BANKS) ||
 		    (fw_store_desc->img_entry_size <
 		     offsetof(struct fwu_image_entry, img_bank_info) +
@@ -217,9 +218,9 @@
 			for (size_t bank_index = 0; bank_index < fw_store_desc->num_banks;
 			     bank_index++) {
 				const struct fwu_img_bank_info *bank_info =
-					(const struct fwu_img_bank_info
-						 *)((const uint8_t *)image_entry->img_bank_info +
-						    bank_index * fw_store_desc->bank_entry_size);
+					(const struct fwu_img_bank_info *)((const uint8_t *)
+					image_entry->img_bank_info + bank_index *
+					fw_store_desc->bank_info_entry_size);
 
 				if (bank_info->accepted)
 					bank_tracker_accept(bank_tracker, bank_index, image_index);
diff --git a/components/service/fwu/fw_store/banked/test/metadata_v2_tests.cpp b/components/service/fwu/fw_store/banked/test/metadata_v2_tests.cpp
index 7e59c6f..d40e637 100644
--- a/components/service/fwu/fw_store/banked/test/metadata_v2_tests.cpp
+++ b/components/service/fwu/fw_store/banked/test/metadata_v2_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <CppUTest/TestHarness.h>
 #include <cstddef>
 
-#include "protocols/service/fwu/packed-c/metadata_v2.h"
+#include "protocols/service/fwu/metadata_v2.h"
 
 /* Tests check FWU metadata protocol definitions are aligned to the FWU-A
  * specification.
@@ -21,26 +21,24 @@
 	/* Check header structure offsets against offsets from spec */
 	UNSIGNED_LONGS_EQUAL(0x00, offsetof(fwu_metadata, crc_32));
 	UNSIGNED_LONGS_EQUAL(0x04, offsetof(fwu_metadata, version));
-	UNSIGNED_LONGS_EQUAL(0x08, offsetof(fwu_metadata, metadata_size));
-	UNSIGNED_LONGS_EQUAL(0x0c, offsetof(fwu_metadata, header_size));
-	/* Note: spec incorrectly says 0x0d - fed back */
-	UNSIGNED_LONGS_EQUAL(0x0e, offsetof(fwu_metadata, active_index));
-	UNSIGNED_LONGS_EQUAL(0x0f, offsetof(fwu_metadata, previous_active_index));
-	UNSIGNED_LONGS_EQUAL(0x10, offsetof(fwu_metadata, bank_state));
+	UNSIGNED_LONGS_EQUAL(0x08, offsetof(fwu_metadata, active_index));
+	UNSIGNED_LONGS_EQUAL(0x0c, offsetof(fwu_metadata, previous_active_index));
+	UNSIGNED_LONGS_EQUAL(0x10, offsetof(fwu_metadata, metadata_size));
+	UNSIGNED_LONGS_EQUAL(0x14, offsetof(fwu_metadata, descriptor_offset));
+	UNSIGNED_LONGS_EQUAL(0x18, offsetof(fwu_metadata, bank_state));
 
 	/* Check header size aligns with expected offset of optional fw_store_desc */
-	/* Note: spec incorrectly says 0x11 - fed back */
-	UNSIGNED_LONGS_EQUAL(0x14, sizeof(struct fwu_metadata));
+	UNSIGNED_LONGS_EQUAL(0x20, sizeof(struct fwu_metadata));
 }
 
 TEST(FwuMetadataV2Tests, checkFwStoreDescStructure)
 {
 	/* Check fw_store_desc structure offsets against offsets from spec */
 	UNSIGNED_LONGS_EQUAL(0x00, offsetof(fwu_fw_store_desc, num_banks));
-	UNSIGNED_LONGS_EQUAL(0x01, offsetof(fwu_fw_store_desc, num_images));
-	UNSIGNED_LONGS_EQUAL(0x03, offsetof(fwu_fw_store_desc, img_entry_size));
-	UNSIGNED_LONGS_EQUAL(0x05, offsetof(fwu_fw_store_desc, bank_entry_size));
-	UNSIGNED_LONGS_EQUAL(0x07, offsetof(fwu_fw_store_desc, img_entry));
+	UNSIGNED_LONGS_EQUAL(0x02, offsetof(fwu_fw_store_desc, num_images));
+	UNSIGNED_LONGS_EQUAL(0x04, offsetof(fwu_fw_store_desc, img_entry_size));
+	UNSIGNED_LONGS_EQUAL(0x06, offsetof(fwu_fw_store_desc, bank_info_entry_size));
+	UNSIGNED_LONGS_EQUAL(0x08, offsetof(fwu_fw_store_desc, img_entry));
 }
 
 TEST(FwuMetadataV2Tests, checkImgEntryStructure)
diff --git a/components/service/fwu/inspector/direct/direct_fw_inspector.c b/components/service/fwu/inspector/direct/direct_fw_inspector.c
index 503cf45..63d64fc 100644
--- a/components/service/fwu/inspector/direct/direct_fw_inspector.c
+++ b/components/service/fwu/inspector/direct/direct_fw_inspector.c
@@ -8,7 +8,7 @@
 #include "direct_fw_inspector.h"
 
 #include "media/volume/index/volume_index.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/agent/fw_directory.h"
 #include "service/fwu/fw_store/banked/volume_id.h"
 #include "service/fwu/installer/installer.h"
diff --git a/components/service/fwu/installer/copy/copy_installer.c b/components/service/fwu/installer/copy/copy_installer.c
index 84543a3..21fd790 100644
--- a/components/service/fwu/installer/copy/copy_installer.c
+++ b/components/service/fwu/installer/copy/copy_installer.c
@@ -12,7 +12,7 @@
 #include <stdlib.h>
 
 #include "media/volume/index/volume_index.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "util.h"
 
 #define COPY_CHUNK_SIZE (4096)
diff --git a/components/service/fwu/installer/factory/default/installer_factory.c b/components/service/fwu/installer/factory/default/installer_factory.c
index 506f963..e697bf8 100644
--- a/components/service/fwu/installer/factory/default/installer_factory.c
+++ b/components/service/fwu/installer/factory/default/installer_factory.c
@@ -25,7 +25,7 @@
  *    storage volume (* n banks). A volume will normally map to a flash partition.
  * 2. SCP firmware, if present, is always updated as a single unit and resides in
  *    a separate storage volume.
- * 3. RSS firmware, if present, is always updated as a single unit and resides in
+ * 3. RSE firmware, if present, is always updated as a single unit and resides in
  *    a separate storage volume.
  */
 
@@ -62,7 +62,7 @@
 	if (installation_type == INSTALL_TYPE_WHOLE_VOLUME) {
 #ifdef RAW_INSTALLER_AVAILABLE
 		static const char *const raw_installer_compatibility[] = {
-			LOCATION_UUID_AP_FW, LOCATION_UUID_SCP_FW, LOCATION_UUID_RSS_FW, NULL
+			LOCATION_UUID_AP_FW, LOCATION_UUID_SCP_FW, LOCATION_UUID_RSE_FW, NULL
 		};
 
 		if (check_supported_locations(raw_installer_compatibility, location_uuid)) {
@@ -79,7 +79,7 @@
 	} else if (installation_type == INSTALL_TYPE_WHOLE_VOLUME_COPY) {
 #ifdef COPY_INSTALLER_AVAILABLE
 		static const char *const copy_installer_compatibility[] = {
-			LOCATION_UUID_AP_FW, LOCATION_UUID_SCP_FW, LOCATION_UUID_RSS_FW, NULL
+			LOCATION_UUID_AP_FW, LOCATION_UUID_SCP_FW, LOCATION_UUID_RSE_FW, NULL
 		};
 
 		if (check_supported_locations(copy_installer_compatibility, location_uuid)) {
diff --git a/components/service/fwu/installer/factory/default/test/default_installer_factory_tests.cpp b/components/service/fwu/installer/factory/default/test/default_installer_factory_tests.cpp
index 213a265..b03d250 100644
--- a/components/service/fwu/installer/factory/default/test/default_installer_factory_tests.cpp
+++ b/components/service/fwu/installer/factory/default/test/default_installer_factory_tests.cpp
@@ -39,7 +39,7 @@
 {
 	struct uuid_octets ap_fw_uuid;
 	struct uuid_octets scp_fw_uuid;
-	struct uuid_octets rss_fw_uuid;
+	struct uuid_octets rse_fw_uuid;
 
 	/* Check configuration operations that will be performed when
 	 * constructing a set of installers for a platform. The platform
@@ -89,25 +89,25 @@
 	installer_index_register(installer);
 	CHECK_TRUE(installer_index_find_by_location_uuid(&scp_fw_uuid));
 
-	/* Configure installers for updating RSS firmware */
-	uuid_guid_octets_from_canonical(&rss_fw_uuid, LOCATION_UUID_RSS_FW);
+	/* Configure installers for updating RSE firmware */
+	uuid_guid_octets_from_canonical(&rse_fw_uuid, LOCATION_UUID_RSE_FW);
 
 	/* Expect no installer to initially be registered */
-	CHECK_FALSE(installer_index_find_by_location_uuid(&rss_fw_uuid));
+	CHECK_FALSE(installer_index_find_by_location_uuid(&rse_fw_uuid));
 
 	/* Configure for whole volume and copy installation */
-	installer = installer_factory_create_installer(INSTALL_TYPE_WHOLE_VOLUME, 0, &rss_fw_uuid);
+	installer = installer_factory_create_installer(INSTALL_TYPE_WHOLE_VOLUME, 0, &rse_fw_uuid);
 	CHECK_TRUE(installer);
 
 	installer_index_register(installer);
-	CHECK_TRUE(installer_index_find_by_location_uuid(&rss_fw_uuid));
+	CHECK_TRUE(installer_index_find_by_location_uuid(&rse_fw_uuid));
 
 	installer =
-		installer_factory_create_installer(INSTALL_TYPE_WHOLE_VOLUME_COPY, 0, &rss_fw_uuid);
+		installer_factory_create_installer(INSTALL_TYPE_WHOLE_VOLUME_COPY, 0, &rse_fw_uuid);
 	CHECK_TRUE(installer);
 
 	installer_index_register(installer);
-	CHECK_TRUE(installer_index_find_by_location_uuid(&rss_fw_uuid));
+	CHECK_TRUE(installer_index_find_by_location_uuid(&rse_fw_uuid));
 
 	/* Now try and construct an installer for an unsupported partition type. */
 	struct uuid_octets unsupported_location_uuid;
diff --git a/components/service/fwu/installer/factory/locations.h b/components/service/fwu/installer/factory/locations.h
index 4df7843..d29f261 100644
--- a/components/service/fwu/installer/factory/locations.h
+++ b/components/service/fwu/installer/factory/locations.h
@@ -26,7 +26,7 @@
 /* Location UUID for SCP firmware */
 #define LOCATION_UUID_SCP_FW "691d5ea3-27fe-4104-badd-7539c00a9095"
 
-/* Location UUID for RSS firmware */
-#define LOCATION_UUID_RSS_FW "c948a156-58cb-4c38-b406-e60bff2223d5"
+/* Location UUID for RSE firmware */
+#define LOCATION_UUID_RSE_FW "c948a156-58cb-4c38-b406-e60bff2223d5"
 
 #endif /* INSTALLER_FACTORY_LOCATIONS_H */
diff --git a/components/service/fwu/installer/installer.c b/components/service/fwu/installer/installer.c
index b69a71c..433ea5a 100644
--- a/components/service/fwu/installer/installer.c
+++ b/components/service/fwu/installer/installer.c
@@ -11,7 +11,7 @@
 #include <stdbool.h>
 #include <stddef.h>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 
 void installer_init(struct installer *installer, enum install_type install_type,
 		    uint32_t location_id, const struct uuid_octets *location_uuid, void *context,
diff --git a/components/service/fwu/installer/raw/raw_installer.c b/components/service/fwu/installer/raw/raw_installer.c
index 0002779..227183e 100644
--- a/components/service/fwu/installer/raw/raw_installer.c
+++ b/components/service/fwu/installer/raw/raw_installer.c
@@ -12,7 +12,7 @@
 #include <string.h>
 
 #include "media/volume/index/volume_index.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/agent/fw_directory.h"
 
 static int raw_installer_begin(void *context, unsigned int current_volume_id,
diff --git a/components/service/fwu/provider/component.cmake b/components/service/fwu/provider/component.cmake
index bf15460..cd1e285 100644
--- a/components/service/fwu/provider/component.cmake
+++ b/components/service/fwu/provider/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -10,4 +10,5 @@
 
 target_sources(${TGT} PRIVATE
 	"${CMAKE_CURRENT_LIST_DIR}/fwu_provider.c"
+	"${CMAKE_CURRENT_LIST_DIR}/fwu_provider_shim.c"
 	)
diff --git a/components/service/fwu/provider/fwu_provider.c b/components/service/fwu/provider/fwu_provider.c
index e94f653..51b712d 100644
--- a/components/service/fwu/provider/fwu_provider.c
+++ b/components/service/fwu/provider/fwu_provider.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,12 +10,17 @@
 
 #include "common/uuid/uuid.h"
 #include "protocols/rpc/common/packed-c/status.h"
-#include "protocols/service/fwu/packed-c/opcodes.h"
-#include "service/fwu/agent/update_agent.h"
+#include "protocols/service/fwu/opcodes.h"
+#include "service/fwu/common/update_agent_interface.h"
 #include "service/fwu/provider/serializer/fwu_provider_serializer.h"
 #include "fwu_uuid.h"
 
+#ifndef FWU_PROVIDER_MAX_PARTIAL_UPDATE_COUNT
+#define FWU_PROVIDER_MAX_PARTIAL_UPDATE_COUNT	(4)
+#endif /* FWU_PROVIDER_MAX_PARTIAL_UPDATE_COUNT */
+
 /* Service request handlers */
+static rpc_status_t discover_handler(void *context, struct rpc_request *req);
 static rpc_status_t begin_staging_handler(void *context, struct rpc_request *req);
 static rpc_status_t end_staging_handler(void *context, struct rpc_request *req);
 static rpc_status_t cancel_staging_handler(void *context, struct rpc_request *req);
@@ -28,31 +33,35 @@
 
 /* Handler mapping table for service */
 static const struct service_handler handler_table[] = {
-	{ TS_FWU_OPCODE_BEGIN_STAGING, begin_staging_handler },
-	{ TS_FWU_OPCODE_END_STAGING, end_staging_handler },
-	{ TS_FWU_OPCODE_CANCEL_STAGING, cancel_staging_handler },
-	{ TS_FWU_OPCODE_OPEN, open_handler },
-	{ TS_FWU_OPCODE_WRITE_STREAM, write_stream_handler },
-	{ TS_FWU_OPCODE_READ_STREAM, read_stream_handler },
-	{ TS_FWU_OPCODE_COMMIT, commit_handler },
-	{ TS_FWU_OPCODE_ACCEPT_IMAGE, accept_image_handler },
-	{ TS_FWU_OPCODE_SELECT_PREVIOUS, select_previous_handler }
+	{ FWU_FUNC_ID_DISCOVER, discover_handler },
+	{ FWU_FUNC_ID_BEGIN_STAGING, begin_staging_handler },
+	{ FWU_FUNC_ID_END_STAGING, end_staging_handler },
+	{ FWU_FUNC_ID_CANCEL_STAGING, cancel_staging_handler },
+	{ FWU_FUNC_ID_OPEN, open_handler },
+	{ FWU_FUNC_ID_WRITE_STREAM, write_stream_handler },
+	{ FWU_FUNC_ID_READ_STREAM, read_stream_handler },
+	{ FWU_FUNC_ID_COMMIT, commit_handler },
+	{ FWU_FUNC_ID_ACCEPT_IMAGE, accept_image_handler },
+	{ FWU_FUNC_ID_SELECT_PREVIOUS, select_previous_handler }
 };
 
 struct rpc_service_interface *fwu_provider_init(struct fwu_provider *context,
 					struct update_agent *update_agent)
 {
 	const struct rpc_uuid service_uuid = { .uuid = TS_FWU_SERVICE_UUID };
+	struct rpc_service_interface *rpc_interface = NULL;
+
 	/* Initialise the fwu_provider */
 	context->update_agent = update_agent;
 
-	for (size_t encoding = 0; encoding < TS_RPC_ENCODING_LIMIT; ++encoding)
-		context->serializers[encoding] = NULL;
-
 	service_provider_init(&context->base_provider, context, &service_uuid, handler_table,
 			      sizeof(handler_table) / sizeof(struct service_handler));
 
-	return service_provider_get_rpc_interface(&context->base_provider);
+	rpc_interface = service_provider_get_rpc_interface(&context->base_provider);
+	if (!rpc_interface)
+		return NULL;
+
+	return fwu_provider_shim_init(&context->shim, rpc_interface);
 }
 
 void fwu_provider_deinit(struct fwu_provider *context)
@@ -60,33 +69,83 @@
 	(void)context;
 }
 
-void fwu_provider_register_serializer(struct fwu_provider *context, unsigned int encoding,
-				      const struct fwu_provider_serializer *serializer)
+static uint16_t generate_function_presence(const struct update_agent *agent,
+					   uint8_t function_presence[FWU_FUNC_ID_COUNT])
 {
-	if (encoding < TS_RPC_ENCODING_LIMIT) {
-		context->serializers[encoding] = serializer;
-	}
+	uint16_t num_func = 0;
+
+#define ADD_FUNC_IF_PRESENT(func, id) \
+do { \
+	if (agent->interface->func != NULL) \
+		function_presence[num_func++] = (id); \
+} while (0)
+
+	ADD_FUNC_IF_PRESENT(discover, FWU_FUNC_ID_DISCOVER);
+	ADD_FUNC_IF_PRESENT(begin_staging, FWU_FUNC_ID_BEGIN_STAGING);
+	ADD_FUNC_IF_PRESENT(end_staging, FWU_FUNC_ID_END_STAGING);
+	ADD_FUNC_IF_PRESENT(cancel_staging, FWU_FUNC_ID_CANCEL_STAGING);
+	ADD_FUNC_IF_PRESENT(open, FWU_FUNC_ID_OPEN);
+	ADD_FUNC_IF_PRESENT(write_stream, FWU_FUNC_ID_WRITE_STREAM);
+	ADD_FUNC_IF_PRESENT(read_stream, FWU_FUNC_ID_READ_STREAM);
+	ADD_FUNC_IF_PRESENT(commit, FWU_FUNC_ID_COMMIT);
+	ADD_FUNC_IF_PRESENT(accept_image, FWU_FUNC_ID_ACCEPT_IMAGE);
+	ADD_FUNC_IF_PRESENT(select_previous, FWU_FUNC_ID_SELECT_PREVIOUS);
+
+#undef ADD_FUNC_IF_PRESENT
+
+	return num_func;
 }
 
-static const struct fwu_provider_serializer *get_fwu_serializer(struct fwu_provider *this_instance,
-								const struct rpc_request *req)
+static rpc_status_t discover_handler(void *context, struct rpc_request *req)
 {
-	const struct fwu_provider_serializer *serializer = NULL;
-	unsigned int encoding = 0;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct fwu_provider *this_instance = (struct fwu_provider *)context;
+	struct fwu_discovery_result discovery_result = { 0 };
+	struct rpc_buffer *resp_buf = &req->response;
 
-	if (encoding < TS_RPC_ENCODING_LIMIT)
-		serializer = this_instance->serializers[encoding];
+	req->service_status = update_agent_discover(this_instance->update_agent, &discovery_result);
 
-	return serializer;
+	if (!req->service_status) {
+		uint16_t num_func = 0;
+		uint8_t function_presence[FWU_FUNC_ID_COUNT] = { 0 };
+
+		num_func = generate_function_presence(this_instance->update_agent,
+						      function_presence);
+
+		rpc_status = fwu_serialize_discover_resp(
+			resp_buf, discovery_result.service_status, discovery_result.version_major,
+			discovery_result.version_minor, num_func, discovery_result.max_payload_size,
+			discovery_result.flags, discovery_result.vendor_specific_flags,
+			function_presence);
+	} else {
+		/*
+		 * The actual service call failed, but the request was successful on the RPC level
+		 */
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
 }
 
 static rpc_status_t begin_staging_handler(void *context, struct rpc_request *req)
 {
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
+	uint32_t vendor_flags = 0;
+	uint32_t partial_update_count = 0;
+	struct uuid_octets update_guid[FWU_PROVIDER_MAX_PARTIAL_UPDATE_COUNT];
 
-	req->service_status = update_agent_begin_staging(this_instance->update_agent);
+	rpc_status = fwu_deserialize_begin_staging_req(
+		req_buf, &vendor_flags, &partial_update_count,
+		FWU_PROVIDER_MAX_PARTIAL_UPDATE_COUNT, update_guid);
 
-	return RPC_SUCCESS;
+	if (rpc_status == RPC_SUCCESS)
+		req->service_status = update_agent_begin_staging(
+			this_instance->update_agent, vendor_flags, partial_update_count,
+			update_guid);
+
+	return rpc_status;
 }
 
 static rpc_status_t end_staging_handler(void *context, struct rpc_request *req)
@@ -112,20 +171,20 @@
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
-	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
-	struct uuid_octets image_type_uuid;
+	struct uuid_octets image_type_uuid = { 0 };
+	uint8_t op_type = 0;
 
-	if (serializer)
-		rpc_status = serializer->deserialize_open_req(req_buf, &image_type_uuid);
+	rpc_status = fwu_deserialize_open_req(req_buf, &image_type_uuid, &op_type);
 
 	if (rpc_status == RPC_SUCCESS) {
 		uint32_t handle = 0;
 		req->service_status =
-			update_agent_open(this_instance->update_agent, &image_type_uuid, &handle);
+			update_agent_open(this_instance->update_agent, &image_type_uuid, op_type,
+					  &handle);
 
 		if (!req->service_status) {
 			struct rpc_buffer *resp_buf = &req->response;
-			rpc_status = serializer->serialize_open_resp(resp_buf, handle);
+			rpc_status = fwu_serialize_open_resp(resp_buf, handle);
 		}
 	}
 
@@ -137,14 +196,11 @@
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
-	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	uint32_t handle = 0;
 	size_t data_len = 0;
 	const uint8_t *data = NULL;
 
-	if (serializer)
-		rpc_status = serializer->deserialize_write_stream_req(req_buf, &handle, &data_len,
-								      &data);
+	rpc_status = fwu_deserialize_write_stream_req(req_buf, &handle, &data_len, &data);
 
 	if (rpc_status == RPC_SUCCESS) {
 		req->service_status = update_agent_write_stream(this_instance->update_agent, handle,
@@ -159,11 +215,9 @@
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
-	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	uint32_t handle = 0;
 
-	if (serializer)
-		rpc_status = serializer->deserialize_read_stream_req(req_buf, &handle);
+	rpc_status = fwu_deserialize_read_stream_req(req_buf, &handle);
 
 	if (rpc_status == RPC_SUCCESS) {
 		struct rpc_buffer *resp_buf = &req->response;
@@ -172,15 +226,14 @@
 		size_t read_len = 0;
 		size_t total_len = 0;
 
-		serializer->read_stream_resp_payload(resp_buf, &payload_buf, &max_payload);
+		fwu_read_stream_resp_payload(resp_buf, &payload_buf, &max_payload);
 
 		req->service_status = update_agent_read_stream(this_instance->update_agent, handle,
 							 payload_buf, max_payload, &read_len,
 							 &total_len);
 
 		if (!req->service_status)
-			rpc_status = serializer->serialize_read_stream_resp(resp_buf, read_len,
-									    total_len);
+			rpc_status = fwu_serialize_read_stream_resp(resp_buf, read_len, total_len);
 
 	}
 
@@ -192,22 +245,22 @@
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
-	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	uint32_t handle = 0;
 	bool accepted = false;
 	size_t max_atomic_len = 0;
 
-	if (serializer)
-		rpc_status = serializer->deserialize_commit_req(req_buf, &handle, &accepted,
-								&max_atomic_len);
+	rpc_status = fwu_deserialize_commit_req(req_buf, &handle, &accepted, &max_atomic_len);
 
 	if (rpc_status == RPC_SUCCESS) {
+		uint32_t progress = 0;
+		uint32_t total_work = 0;
+
 		req->service_status = update_agent_commit(this_instance->update_agent, handle,
-							  accepted);
+							  accepted, 0, &progress, &total_work);
 
 		if (!req->service_status) {
 			struct rpc_buffer *resp_buf = &req->response;
-			rpc_status = serializer->serialize_commit_resp(resp_buf, 0, 0);
+			rpc_status = fwu_serialize_commit_resp(resp_buf, progress, total_work);
 		}
 	}
 
@@ -219,15 +272,13 @@
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 	struct rpc_buffer *req_buf = &req->request;
 	struct fwu_provider *this_instance = (struct fwu_provider *)context;
-	const struct fwu_provider_serializer *serializer = get_fwu_serializer(this_instance, req);
 	struct uuid_octets image_type_uuid;
 
-	if (serializer)
-		rpc_status = serializer->deserialize_accept_req(req_buf, &image_type_uuid);
+	rpc_status = fwu_deserialize_accept_req(req_buf, &image_type_uuid);
 
 	if (rpc_status == RPC_SUCCESS)
-		req->service_status = update_agent_accept(this_instance->update_agent,
-							  &image_type_uuid);
+		req->service_status = update_agent_accept_image(this_instance->update_agent,
+								&image_type_uuid);
 
 	return rpc_status;
 }
diff --git a/components/service/fwu/provider/fwu_provider.h b/components/service/fwu/provider/fwu_provider.h
index 037889a..d762bce 100644
--- a/components/service/fwu/provider/fwu_provider.h
+++ b/components/service/fwu/provider/fwu_provider.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,6 +10,7 @@
 #include "protocols/rpc/common/packed-c/encoding.h"
 #include "rpc/common/endpoint/rpc_service_interface.h"
 #include "service/common/provider/service_provider.h"
+#include "fwu_provider_shim.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -32,7 +33,7 @@
  */
 struct fwu_provider {
 	struct service_provider base_provider;
-	const struct fwu_provider_serializer *serializers[TS_RPC_ENCODING_LIMIT];
+	struct fwu_provider_shim shim;
 	struct update_agent *update_agent;
 };
 
@@ -54,16 +55,6 @@
  */
 void fwu_provider_deinit(struct fwu_provider *context);
 
-/**
- * \brief Register a serializer
- *
- * \param[in] context    The subject fwu_provider context
- * \param[in] encoding   The encoding scheme
- * \param[in] serializer The serializer
- */
-void fwu_provider_register_serializer(struct fwu_provider *context, unsigned int encoding,
-				      const struct fwu_provider_serializer *serializer);
-
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/components/service/fwu/provider/fwu_provider_shim.c b/components/service/fwu/provider/fwu_provider_shim.c
new file mode 100644
index 0000000..6d67870
--- /dev/null
+++ b/components/service/fwu/provider/fwu_provider_shim.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fwu_provider_shim.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "util.h"
+
+static rpc_status_t receive(void *context, struct rpc_request *req)
+{
+	struct rpc_service_interface *fwu_rpc_interface = (struct rpc_service_interface *)context;
+	struct fwu_request_header *req_header = NULL;
+	struct fwu_response_header *resp_header = NULL;
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct rpc_request fwu_req = { 0 };
+
+	if (req->request.data_length < sizeof(*req_header))
+		return RPC_ERROR_INVALID_REQUEST_BODY;
+
+	if (req->response.size < sizeof(*resp_header))
+		return RPC_ERROR_INVALID_RESPONSE_BODY;
+
+	req_header = (struct fwu_request_header *)req->request.data;
+	resp_header = (struct fwu_response_header *)req->response.data;
+
+	/* Build new RPC request without the request headers */
+	fwu_req = *req;
+	fwu_req.opcode = req_header->func_id & 0xffff;
+	fwu_req.request.data = req_header->payload;
+	fwu_req.request.data_length -= sizeof(*req_header);
+	fwu_req.request.size -= sizeof(*req_header);
+	fwu_req.response.data = resp_header->payload;
+	fwu_req.response.size -= sizeof(*resp_header);
+
+	rpc_status = rpc_service_receive(fwu_rpc_interface, &fwu_req);
+	if (rpc_status != RPC_SUCCESS)
+		return rpc_status;
+
+	/* Insert service status into response buffer */
+	resp_header->status = fwu_req.service_status;
+
+	req->service_status = fwu_req.service_status;
+
+	/* Update response data length */
+	if (ADD_OVERFLOW(fwu_req.response.data_length, sizeof(uint32_t),
+			 &req->response.data_length))
+		return RPC_ERROR_INVALID_RESPONSE_BODY;
+
+	if (req->response.data_length > req->response.size)
+		return RPC_ERROR_INVALID_RESPONSE_BODY;
+
+	return rpc_status;
+}
+
+struct rpc_service_interface *
+fwu_provider_shim_init(struct fwu_provider_shim *shim,
+		       struct rpc_service_interface *fwu_rpc_interface)
+{
+	shim->shim_rpc_interface.receive = receive;
+	shim->shim_rpc_interface.context = fwu_rpc_interface;
+	shim->shim_rpc_interface.uuid = fwu_rpc_interface->uuid;
+
+	return &shim->shim_rpc_interface;
+}
+
+void fwu_provider_shim_deinit(struct fwu_provider_shim *shim)
+{
+	(void)shim;
+}
diff --git a/components/service/fwu/provider/fwu_provider_shim.h b/components/service/fwu/provider/fwu_provider_shim.h
new file mode 100644
index 0000000..0a411f9
--- /dev/null
+++ b/components/service/fwu/provider/fwu_provider_shim.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FWU_PROVIDER_SHIM_H
+#define FWU_PROVIDER_SHIM_H
+
+#include "rpc/common/endpoint/rpc_service_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief PSA FWU provider shim layer
+ *
+ * The PSA FWU forwards the function ID and the service status in the beginning of the shared
+ * memory. This layer handles the extraction of the function ID and the insertion of service status,
+ * so individual function handlers don't have to do that.
+ */
+
+struct fwu_provider_shim {
+	struct rpc_service_interface shim_rpc_interface;
+};
+
+struct rpc_service_interface *fwu_provider_shim_init(
+	struct fwu_provider_shim *shim, struct rpc_service_interface *fwu_rpc_interface);
+
+void fwu_provider_shim_deinit(struct fwu_provider_shim *shim);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* FWU_PROVIDER_SHIM_H */
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/service/fwu/provider/serializer/component.cmake
similarity index 70%
copy from components/service/fwu/provider/serializer/packed-c/component.cmake
copy to components/service/fwu/provider/serializer/component.cmake
index 4209cae..d881b60 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/service/fwu/provider/serializer/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
+	"${CMAKE_CURRENT_LIST_DIR}/fwu_provider_serializer.c"
 	)
diff --git a/components/service/fwu/provider/serializer/fwu_provider_serializer.c b/components/service/fwu/provider/serializer/fwu_provider_serializer.c
new file mode 100644
index 0000000..5397760
--- /dev/null
+++ b/components/service/fwu/provider/serializer/fwu_provider_serializer.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#include "fwu_provider_serializer.h"
+
+#include <string.h>
+
+#include "protocols/rpc/common/packed-c/status.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "util.h"
+
+rpc_status_t fwu_serialize_discover_resp(const struct rpc_buffer *resp_buf, int16_t service_status,
+					 uint8_t version_major, uint8_t version_minor,
+					 uint16_t num_func, uint64_t max_payload_size,
+					 uint32_t flags, uint32_t vendor_specific_flags,
+					 uint8_t *function_presence)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_RESPONSE_BODY;
+	struct fwu_discover_out *resp_msg = NULL;
+	size_t len = 0;
+
+	if (ADD_OVERFLOW(sizeof(*resp_msg), num_func, &len))
+		return RPC_ERROR_INVALID_RESPONSE_BODY;
+
+	if (len <= resp_buf->size) {
+		resp_msg = (struct fwu_discover_out *)resp_buf->data;
+
+		resp_msg->service_status = service_status;
+		resp_msg->version_major = version_major;
+		resp_msg->version_minor = version_minor;
+		resp_msg->off_function_presence =
+			offsetof(struct fwu_discover_out, function_presence);
+		resp_msg->num_func = num_func;
+		resp_msg->max_payload_size = max_payload_size;
+		resp_msg->flags = flags;
+		resp_msg->vendor_specific_flags = vendor_specific_flags;
+		memcpy(resp_msg->function_presence, function_presence, num_func);
+
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
+rpc_status_t fwu_deserialize_begin_staging_req(const struct rpc_buffer *req_buf,
+					       uint32_t *vendor_flags,
+					       uint32_t *partial_update_count,
+					       uint32_t max_update_count,
+					       struct uuid_octets *update_guid)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	size_t expected_fixed_len = sizeof(struct fwu_begin_staging_in);
+
+	if (expected_fixed_len <= req_buf->data_length) {
+		const struct fwu_begin_staging_in *recv_msg =
+			(const struct fwu_begin_staging_in *)req_buf->data;
+		size_t full_len = 0;
+
+		if (ADD_OVERFLOW(expected_fixed_len, recv_msg->partial_update_count, &full_len))
+			return RPC_ERROR_INVALID_REQUEST_BODY;
+
+		if (recv_msg->partial_update_count > max_update_count)
+			return RPC_ERROR_INTERNAL;
+
+		*vendor_flags = recv_msg->vendor_flags;
+		*partial_update_count = recv_msg->partial_update_count;
+
+		memcpy(update_guid, recv_msg->update_guid,
+		       UUID_OCTETS_LEN * recv_msg->partial_update_count);
+
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
+rpc_status_t fwu_deserialize_open_req(const struct rpc_buffer *req_buf,
+				      struct uuid_octets *image_type_uuid,
+				      uint8_t *op_type)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	size_t expected_fixed_len = sizeof(struct fwu_open_in);
+
+	if (expected_fixed_len <= req_buf->data_length) {
+		const struct fwu_open_in *recv_msg =
+			(const struct fwu_open_in *)req_buf->data;
+
+		if (recv_msg->op_type == FWU_OPEN_OP_TYPE_READ ||
+		    recv_msg->op_type == FWU_OPEN_OP_TYPE_WRITE) {
+			memcpy(image_type_uuid->octets, recv_msg->image_type_uuid, UUID_OCTETS_LEN);
+			*op_type = recv_msg->op_type;
+			rpc_status = RPC_SUCCESS;
+		} else {
+			rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+		}
+	}
+
+	return rpc_status;
+}
+
+rpc_status_t fwu_serialize_open_resp(struct rpc_buffer *resp_buf, uint32_t handle)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	size_t fixed_len = sizeof(struct fwu_open_out);
+
+	if (fixed_len <= resp_buf->size) {
+		struct fwu_open_out *resp_msg = (struct fwu_open_out *)resp_buf->data;
+
+		resp_msg->handle = handle;
+
+		resp_buf->data_length = fixed_len;
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
+/* Operation: write_stream */
+rpc_status_t fwu_deserialize_write_stream_req(const struct rpc_buffer *req_buf, uint32_t *handle,
+					      size_t *data_length, const uint8_t **data)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	size_t expected_fixed_len = sizeof(struct fwu_write_stream_in);
+
+	if (expected_fixed_len <= req_buf->data_length) {
+		const struct fwu_write_stream_in *recv_msg =
+			(const struct fwu_write_stream_in *)req_buf->data;
+
+		*handle = recv_msg->handle;
+		*data_length = recv_msg->data_len;
+		*data = recv_msg->payload;
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
+/* Operation: read_stream */
+rpc_status_t fwu_deserialize_read_stream_req(const struct rpc_buffer *req_buf, uint32_t *handle)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	size_t expected_fixed_len = sizeof(struct fwu_read_stream_in);
+
+	if (expected_fixed_len <= req_buf->data_length) {
+		const struct fwu_read_stream_in *recv_msg =
+			(const struct fwu_read_stream_in *)req_buf->data;
+
+		*handle = recv_msg->handle;
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
+void fwu_read_stream_resp_payload(const struct rpc_buffer *resp_buf, uint8_t **payload_buf,
+				  size_t *max_payload)
+{
+	struct fwu_read_stream_out *resp_msg = (struct fwu_read_stream_out *)resp_buf->data;
+	size_t fixed_len = offsetof(struct fwu_read_stream_out, payload);
+
+	*max_payload = 0;
+	*payload_buf = resp_msg->payload;
+
+	if (fixed_len < resp_buf->size)
+		*max_payload = resp_buf->size - fixed_len;
+}
+
+rpc_status_t fwu_serialize_read_stream_resp(struct rpc_buffer *resp_buf, size_t read_bytes,
+					    size_t total_bytes)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct fwu_read_stream_out *resp_msg = (struct fwu_read_stream_out *)resp_buf->data;
+	size_t proto_overhead = offsetof(struct fwu_read_stream_out, payload);
+
+	if (read_bytes > (SIZE_MAX - proto_overhead))
+		return RPC_ERROR_INVALID_VALUE;
+
+	size_t required_len = proto_overhead + read_bytes;
+
+	if (required_len <= resp_buf->size) {
+		resp_msg->read_bytes = read_bytes;
+		resp_msg->total_bytes = total_bytes;
+
+		resp_buf->data_length = required_len;
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
+/* Operation: commit */
+rpc_status_t fwu_deserialize_commit_req(const struct rpc_buffer *req_buf, uint32_t *handle,
+					bool *accepted, size_t *max_atomic_len)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	size_t expected_fixed_len = sizeof(struct fwu_commit_in);
+
+	if (expected_fixed_len <= req_buf->data_length) {
+		const struct fwu_commit_in *recv_msg =
+			(const struct fwu_commit_in *)req_buf->data;
+
+		*handle = recv_msg->handle;
+		*accepted = (recv_msg->acceptance_req == 0);
+		*max_atomic_len = recv_msg->max_atomic_len;
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
+rpc_status_t fwu_serialize_commit_resp(struct rpc_buffer *resp_buf, size_t progress,
+				       size_t total_work)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
+	struct fwu_commit_out *resp_msg = (struct fwu_commit_out *)resp_buf->data;
+
+	size_t required_len = sizeof(struct fwu_commit_out);
+
+	if (required_len <= resp_buf->size) {
+		resp_msg->progress = progress;
+		resp_msg->total_work = total_work;
+
+		resp_buf->data_length = required_len;
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
+
+/* Operation: accept_image */
+rpc_status_t fwu_deserialize_accept_req(const struct rpc_buffer *req_buf,
+					struct uuid_octets *image_type_uuid)
+{
+	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
+	size_t expected_fixed_len = sizeof(struct fwu_accept_image_in);
+
+	if (expected_fixed_len <= req_buf->data_length) {
+		const struct fwu_accept_image_in *recv_msg =
+			(const struct fwu_accept_image_in *)req_buf->data;
+
+		memcpy(image_type_uuid->octets, recv_msg->image_type_uuid, UUID_OCTETS_LEN);
+		rpc_status = RPC_SUCCESS;
+	}
+
+	return rpc_status;
+}
diff --git a/components/service/fwu/provider/serializer/fwu_provider_serializer.h b/components/service/fwu/provider/serializer/fwu_provider_serializer.h
index c9df194..7c30429 100644
--- a/components/service/fwu/provider/serializer/fwu_provider_serializer.h
+++ b/components/service/fwu/provider/serializer/fwu_provider_serializer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,45 +14,49 @@
 #include "common/uuid/uuid.h"
 #include "rpc/common/endpoint/rpc_service_interface.h"
 
-/* Provides a common interface for parameter serialization operations
- * for the fwu service provider. Allows alternative serialization
- * protocols to be used without hard-wiring a particular protocol
- * into the service provider code. A concrete serializer must
- * implement this interface.
- */
-struct fwu_provider_serializer {
-	/* Operation: open */
-	rpc_status_t (*deserialize_open_req)(const struct rpc_buffer *req_buf,
-					     struct uuid_octets *image_type_uuid);
+/* Operation: discover */
+rpc_status_t fwu_serialize_discover_resp(const struct rpc_buffer *resp_buf, int16_t service_status,
+					 uint8_t version_major, uint8_t version_minor,
+					 uint16_t num_func, uint64_t max_payload_size,
+					 uint32_t flags, uint32_t vendor_specific_flags,
+					 uint8_t *function_presence);
 
-	rpc_status_t (*serialize_open_resp)(struct rpc_buffer *resp_buf, uint32_t handle);
+/* Operation: begin staging */
+rpc_status_t fwu_deserialize_begin_staging_req(const struct rpc_buffer *req_buf,
+					       uint32_t *vendor_flags,
+					       uint32_t *partial_update_count,
+					       uint32_t max_update_count,
+					       struct uuid_octets *update_guid);
 
-	/* Operation: write_stream */
-	rpc_status_t (*deserialize_write_stream_req)(const struct rpc_buffer *req_buf,
-						     uint32_t *handle, size_t *data_len,
-						     const uint8_t **data);
+/* Operation: open */
+rpc_status_t fwu_deserialize_open_req(const struct rpc_buffer *req_buf,
+				      struct uuid_octets *image_type_uuid,
+				      uint8_t *op_type);
 
-	/* Operation: read_stream */
-	rpc_status_t (*deserialize_read_stream_req)(const struct rpc_buffer *req_buf,
-						    uint32_t *handle);
+rpc_status_t fwu_serialize_open_resp(struct rpc_buffer *resp_buf, uint32_t handle);
 
-	void (*read_stream_resp_payload)(const struct rpc_buffer *resp_buf,
-					 uint8_t **payload_buf, size_t *max_payload);
+/* Operation: write_stream */
+rpc_status_t fwu_deserialize_write_stream_req(const struct rpc_buffer *req_buf, uint32_t *handle,
+					      size_t *data_length, const uint8_t **data);
 
-	rpc_status_t (*serialize_read_stream_resp)(struct rpc_buffer *resp_buf,
-						   size_t read_bytes, size_t total_bytes);
+/* Operation: read_stream */
+rpc_status_t fwu_deserialize_read_stream_req(const struct rpc_buffer *req_buf, uint32_t *handle);
 
-	/* Operation: commit */
-	rpc_status_t (*deserialize_commit_req)(const struct rpc_buffer *req_buf,
-					       uint32_t *handle, bool *accepted,
-					       size_t *max_atomic_len);
+void fwu_read_stream_resp_payload(const struct rpc_buffer *resp_buf, uint8_t **payload_buf,
+				  size_t *max_payload);
 
-	rpc_status_t (*serialize_commit_resp)(struct rpc_buffer *resp_buf, size_t progress,
-					      size_t total_work);
+rpc_status_t fwu_serialize_read_stream_resp(struct rpc_buffer *resp_buf, size_t read_bytes,
+					    size_t total_bytes);
 
-	/* Operation: accept_image */
-	rpc_status_t (*deserialize_accept_req)(const struct rpc_buffer *req_buf,
-					       struct uuid_octets *image_type_uuid);
-};
+/* Operation: commit */
+rpc_status_t fwu_deserialize_commit_req(const struct rpc_buffer *req_buf, uint32_t *handle,
+					bool *accepted, size_t *max_atomic_len);
+
+rpc_status_t fwu_serialize_commit_resp(struct rpc_buffer *resp_buf, size_t progress,
+				       size_t total_work);
+
+/* Operation: accept_image */
+rpc_status_t fwu_deserialize_accept_req(const struct rpc_buffer *req_buf,
+					struct uuid_octets *image_type_uuid);
 
 #endif /* FWU_PROVIDER_SERIALIZER_H */
diff --git a/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.c b/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.c
deleted file mode 100644
index cb013d4..0000000
--- a/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-#include "packedc_fwu_provider_serializer.h"
-
-#include <string.h>
-
-#include "protocols/rpc/common/packed-c/status.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
-
-static rpc_status_t deserialize_open_req(const struct rpc_buffer *req_buf,
-					 struct uuid_octets *image_type_uuid)
-{
-	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
-	size_t expected_fixed_len = sizeof(struct ts_fwu_open_in);
-
-	if (expected_fixed_len <= req_buf->data_length) {
-		const struct ts_fwu_open_in *recv_msg =
-			(const struct ts_fwu_open_in *)req_buf->data;
-
-		memcpy(image_type_uuid->octets, recv_msg->image_type_uuid, UUID_OCTETS_LEN);
-
-		rpc_status = RPC_SUCCESS;
-	}
-
-	return rpc_status;
-}
-
-static rpc_status_t serialize_open_resp(struct rpc_buffer *resp_buf, uint32_t handle)
-{
-	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
-	size_t fixed_len = sizeof(struct ts_fwu_open_out);
-
-	if (fixed_len <= resp_buf->size) {
-		struct ts_fwu_open_out *resp_msg = (struct ts_fwu_open_out *)resp_buf->data;
-
-		resp_msg->handle = handle;
-
-		resp_buf->data_length = fixed_len;
-		rpc_status = RPC_SUCCESS;
-	}
-
-	return rpc_status;
-}
-
-/* Operation: write_stream */
-static rpc_status_t deserialize_write_stream_req(const struct rpc_buffer *req_buf,
-						 uint32_t *handle, size_t *data_length,
-						 const uint8_t **data)
-{
-	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
-	size_t expected_fixed_len = sizeof(struct ts_fwu_write_stream_in);
-
-	if (expected_fixed_len <= req_buf->data_length) {
-		const struct ts_fwu_write_stream_in *recv_msg =
-			(const struct ts_fwu_write_stream_in *)req_buf->data;
-
-		*handle = recv_msg->handle;
-		*data_length = recv_msg->data_len;
-		*data = recv_msg->payload;
-		rpc_status = RPC_SUCCESS;
-	}
-
-	return rpc_status;
-}
-
-/* Operation: read_stream */
-static rpc_status_t deserialize_read_stream_req(const struct rpc_buffer *req_buf,
-						uint32_t *handle)
-{
-	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
-	size_t expected_fixed_len = sizeof(struct ts_fwu_read_stream_in);
-
-	if (expected_fixed_len <= req_buf->data_length) {
-		const struct ts_fwu_read_stream_in *recv_msg =
-			(const struct ts_fwu_read_stream_in *)req_buf->data;
-
-		*handle = recv_msg->handle;
-		rpc_status = RPC_SUCCESS;
-	}
-
-	return rpc_status;
-}
-
-static void read_stream_resp_payload(const struct rpc_buffer *resp_buf, uint8_t **payload_buf,
-				     size_t *max_payload)
-{
-	struct ts_fwu_read_stream_out *resp_msg = (struct ts_fwu_read_stream_out *)resp_buf->data;
-	size_t fixed_len = offsetof(struct ts_fwu_read_stream_out, payload);
-
-	*max_payload = 0;
-	*payload_buf = resp_msg->payload;
-
-	if (fixed_len < resp_buf->size)
-		*max_payload = resp_buf->size - fixed_len;
-}
-
-static rpc_status_t serialize_read_stream_resp(struct rpc_buffer *resp_buf, size_t read_bytes,
-					       size_t total_bytes)
-{
-	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
-	struct ts_fwu_read_stream_out *resp_msg = (struct ts_fwu_read_stream_out *)resp_buf->data;
-	size_t proto_overhead = offsetof(struct ts_fwu_read_stream_out, payload);
-
-	if (read_bytes > (SIZE_MAX - proto_overhead))
-		return RPC_ERROR_INVALID_VALUE;
-
-	size_t required_len = proto_overhead + read_bytes;
-
-	if (required_len <= resp_buf->size) {
-		resp_msg->read_bytes = read_bytes;
-		resp_msg->total_bytes = total_bytes;
-
-		resp_buf->data_length = required_len;
-		rpc_status = RPC_SUCCESS;
-	}
-
-	return rpc_status;
-}
-
-/* Operation: commit */
-static rpc_status_t deserialize_commit_req(const struct rpc_buffer *req_buf, uint32_t *handle,
-					   bool *accepted, size_t *max_atomic_len)
-{
-	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
-	size_t expected_fixed_len = sizeof(struct ts_fwu_commit_in);
-
-	if (expected_fixed_len <= req_buf->data_length) {
-		const struct ts_fwu_commit_in *recv_msg =
-			(const struct ts_fwu_commit_in *)req_buf->data;
-
-		*handle = recv_msg->handle;
-		*accepted = (recv_msg->acceptance_req == 0);
-		*max_atomic_len = recv_msg->max_atomic_len;
-		rpc_status = RPC_SUCCESS;
-	}
-
-	return rpc_status;
-}
-
-static rpc_status_t serialize_commit_resp(struct rpc_buffer *resp_buf, size_t progress,
-					  size_t total_work)
-{
-	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
-	struct ts_fwu_commit_out *resp_msg = (struct ts_fwu_commit_out *)resp_buf->data;
-
-	size_t required_len = sizeof(struct ts_fwu_commit_out);
-
-	if (required_len <= resp_buf->size) {
-		resp_msg->progress = progress;
-		resp_msg->total_work = total_work;
-
-		resp_buf->data_length = required_len;
-		rpc_status = RPC_SUCCESS;
-	}
-
-	return rpc_status;
-}
-
-/* Operation: accept_image */
-static rpc_status_t deserialize_accept_req(const struct rpc_buffer *req_buf,
-					   struct uuid_octets *image_type_uuid)
-{
-	rpc_status_t rpc_status = RPC_ERROR_INVALID_REQUEST_BODY;
-	size_t expected_fixed_len = sizeof(struct ts_fwu_accept_image_in);
-
-	if (expected_fixed_len <= req_buf->data_length) {
-		const struct ts_fwu_accept_image_in *recv_msg =
-			(const struct ts_fwu_accept_image_in *)req_buf->data;
-
-		memcpy(image_type_uuid->octets, recv_msg->image_type_uuid, UUID_OCTETS_LEN);
-		rpc_status = RPC_SUCCESS;
-	}
-
-	return rpc_status;
-}
-
-/* Singleton method to provide access to the serializer instance */
-const struct fwu_provider_serializer *packedc_fwu_provider_serializer_instance(void)
-{
-	static const struct fwu_provider_serializer instance = {
-		deserialize_open_req,	     serialize_open_resp,      deserialize_write_stream_req,
-		deserialize_read_stream_req, read_stream_resp_payload, serialize_read_stream_resp,
-		deserialize_commit_req,	     serialize_commit_resp,    deserialize_accept_req
-	};
-
-	return &instance;
-}
diff --git a/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.h b/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.h
deleted file mode 100644
index e1baeed..0000000
--- a/components/service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef PACKEDC_FWU_PROVIDER_SERIALIZER_H
-#define PACKEDC_FWU_PROVIDER_SERIALIZER_H
-
-#include "service/fwu/provider/serializer/fwu_provider_serializer.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Singleton method to provide access to the packed-c serializer
- * for the fwu service provider.
- */
-const struct fwu_provider_serializer *packedc_fwu_provider_serializer_instance(void);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* PACKEDC_FWU_PROVIDER_SERIALIZER_H */
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/service/fwu/psa_fwu_m/agent/component.cmake
similarity index 72%
copy from components/service/fwu/provider/serializer/packed-c/component.cmake
copy to components/service/fwu/psa_fwu_m/agent/component.cmake
index 4209cae..adffc44 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/service/fwu/psa_fwu_m/agent/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
-	)
+	"${CMAKE_CURRENT_LIST_DIR}/psa_fwu_m_update_agent.c"
+)
diff --git a/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c b/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c
new file mode 100644
index 0000000..6de9ba7
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.c
@@ -0,0 +1,673 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "psa_fwu_m_update_agent.h"
+#include "common/uuid/uuid.h"
+#include "service/fwu/psa_fwu_m/interface/update.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "protocols/service/fwu/status.h"
+#include "util.h"
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef PSA_FWU_M_MAX_HANDLES
+#define PSA_FWU_M_MAX_HANDLES	(8)
+#endif /* PSA_FWU_M_MAX_HANDLES */
+
+#define FWU_INVALID_HANDLE	(0xffffffff)
+
+enum psa_fwu_m_state {
+	regular,
+	staging,
+	trial,
+};
+
+struct psa_fwu_m_update_agent;
+
+struct psa_fwu_m_image {
+	struct uuid_octets uuid;
+	psa_fwu_component_t component;
+	bool selected_for_staging;
+	bool accepted;
+	int (*read)(struct psa_fwu_m_update_agent *agent, struct psa_fwu_m_image *image,
+		    uint8_t *buf, size_t buf_size, size_t *read_len, size_t *total_len);
+	int (*write)(struct psa_fwu_m_update_agent *agent, struct psa_fwu_m_image *image,
+		     size_t data_offset, const uint8_t *data, size_t data_len);
+};
+
+struct psa_fwu_m_handle {
+	bool used;
+	size_t current_offset;
+	uint8_t op_type;
+	struct psa_fwu_m_image *image;
+};
+
+struct psa_fwu_m_update_agent {
+	struct psa_fwu_m_image *images;
+	size_t image_count;
+	uint32_t max_payload_size;
+	enum psa_fwu_m_state state;
+	struct psa_fwu_m_handle handles[PSA_FWU_M_MAX_HANDLES];
+};
+
+static int cancel_staging(void *context);
+
+static int psa_status_to_fwu_status(psa_status_t psa_status)
+{
+	switch (psa_status) {
+	case PSA_SUCCESS:
+		return FWU_STATUS_SUCCESS;
+
+	case PSA_ERROR_DOES_NOT_EXIST:
+		return FWU_STATUS_UNKNOWN;
+
+	case PSA_ERROR_INVALID_ARGUMENT:
+		return FWU_STATUS_OUT_OF_BOUNDS;
+
+	case PSA_ERROR_INVALID_SIGNATURE:
+		return FWU_STATUS_AUTH_FAIL;
+
+	case PSA_ERROR_NOT_PERMITTED:
+		return FWU_STATUS_NO_PERMISSION;
+
+	case PSA_ERROR_BAD_STATE:
+	default:
+		return FWU_STATUS_DENIED;
+	}
+}
+
+/* Image functions */
+static struct psa_fwu_m_image *find_image(struct psa_fwu_m_update_agent *agent,
+					  const struct uuid_octets *uuid)
+{
+	size_t i = 0;
+
+	for (i = 0; i < agent->image_count; i++)
+		if (uuid_is_equal(uuid->octets, agent->images[i].uuid.octets))
+			return &agent->images[i];
+
+	return NULL;
+}
+
+static int image_write(struct psa_fwu_m_update_agent *agent, struct psa_fwu_m_image *image,
+		       size_t data_offset, const uint8_t *data, size_t data_len)
+{
+	return psa_status_to_fwu_status(
+		psa_fwu_write(image->component, data_offset, data, data_len));
+}
+
+/* Image directory functions */
+uint32_t image_version_to_uint(psa_fwu_image_version_t version)
+{
+	uint32_t result = 0;
+
+	result |= ((uint32_t)version.major) << 24;
+	result |= ((uint32_t)version.minor) << 16;
+	result |= (uint32_t)version.patch;
+	/* There's no room for the build number */
+
+	return result;
+}
+
+int image_directory_read(struct psa_fwu_m_update_agent *agent, struct psa_fwu_m_image *image,
+			 uint8_t *buf, size_t buf_size, size_t *read_len, size_t *total_len)
+{
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	psa_fwu_component_info_t component_info = { 0 };
+	struct fwu_image_directory *directory = NULL;
+	size_t image_count = agent->image_count - 1; /* Do not return Image directory */
+	size_t image_info_size = 0;
+	size_t i = 0;
+
+	*read_len = 0;
+	*total_len = 0;
+
+	/* Calculate total length */
+	if (MUL_OVERFLOW(sizeof(struct fwu_image_info_entry), image_count, &image_info_size))
+		return FWU_STATUS_DENIED; /* LCOV_EXCL_LINE */
+
+	if (ADD_OVERFLOW(sizeof(struct fwu_image_directory), image_info_size, total_len))
+		return FWU_STATUS_DENIED; /* LCOV_EXCL_LINE */
+
+	/*
+	 * If the directory structure doesn't fit into the buffer return SUCCESS with total_len set
+	 * and read_len = 0.
+	 */
+	if (*total_len > buf_size)
+		return FWU_STATUS_SUCCESS;
+
+	directory = (struct fwu_image_directory *)buf;
+	directory->directory_version = FWU_IMAGE_DIRECTORY_VERSION;
+	directory->img_info_offset = offsetof(struct fwu_image_directory, img_info_entry);
+	directory->num_images = image_count;
+	directory->correct_boot = 1; /* Set to 1 and then set to 0 if any image is not accepted */
+	directory->img_info_size = sizeof(struct fwu_image_info_entry);
+	directory->reserved = 0;
+
+	for (i = 0; i < image_count; i++) {
+		struct fwu_image_info_entry *entry = &directory->img_info_entry[i];
+		struct psa_fwu_m_image *image = &agent->images[i];
+
+		psa_status = psa_fwu_query(image->component, &component_info);
+		if (psa_status != PSA_SUCCESS)
+			return psa_status_to_fwu_status(psa_status);
+
+		memcpy(entry->img_type_uuid, image->uuid.octets, sizeof(entry->img_type_uuid));
+		entry->client_permissions = 0x1; /* Only write is supported by the API */
+		entry->img_max_size = component_info.max_size;
+		entry->lowest_accepted_version = 0; /* This information is not available */
+		entry->img_version = image_version_to_uint(component_info.version);
+		if (component_info.state == PSA_FWU_UPDATED) {
+			entry->accepted = 1;
+		} else {
+			entry->accepted = 0;
+			directory->correct_boot = 0;
+		}
+		entry->reserved = 0;
+	}
+
+	*read_len = *total_len;
+
+	return FWU_STATUS_SUCCESS;
+}
+
+/* Image handle functions */
+static uint32_t allocate_handle(struct psa_fwu_m_update_agent *agent, struct psa_fwu_m_image *image,
+				uint8_t op_type)
+{
+	size_t i = 0;
+
+	for (i = 0; i < ARRAY_SIZE(agent->handles); i++) {
+		struct psa_fwu_m_handle *handle = &agent->handles[i];
+
+		if (!handle->used) {
+			handle->used = true;
+			handle->current_offset = 0;
+			handle->op_type = op_type;
+			handle->image = image;
+
+			return i;
+		}
+	}
+
+	return FWU_INVALID_HANDLE;
+}
+
+static struct psa_fwu_m_handle *get_handle(struct psa_fwu_m_update_agent *agent,
+					   uint32_t handle_index)
+{
+	if (handle_index >= ARRAY_SIZE(agent->handles))
+		return NULL;
+
+	if (!agent->handles[handle_index].used)
+		return NULL;
+
+	return &agent->handles[handle_index];
+}
+
+static void free_handle(struct psa_fwu_m_handle *handle)
+{
+	*handle = (struct psa_fwu_m_handle){ 0 };
+}
+
+/* Misc functions */
+static int clean(void *context)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	uint32_t i = 0;
+
+	for (i = 0; i < agent->image_count; i++) {
+		struct psa_fwu_m_image *image = &agent->images[i];
+
+		/* Skip read-only images */
+		if (!image->write)
+			continue;
+
+		psa_status = psa_fwu_clean(image->component);
+		if (psa_status != PSA_SUCCESS)
+			return psa_status_to_fwu_status(psa_status);
+
+		image->selected_for_staging = false;
+		image->accepted = false;
+	}
+
+	return FWU_STATUS_SUCCESS;
+}
+
+void set_agent_state(struct psa_fwu_m_update_agent *agent, enum psa_fwu_m_state state)
+{
+	struct psa_fwu_m_image *image = NULL;
+	size_t i = 0;
+
+	if (state == regular) {
+		for (i = 0; i < agent->image_count; i++) {
+			image = &agent->images[i];
+
+			image->selected_for_staging = false;
+			image->accepted = false;
+		}
+	}
+
+	agent->state = state;
+}
+
+/* Update agent interface */
+static int discover(void *context, struct fwu_discovery_result *result)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+
+	result->service_status = 0;
+	result->version_major = FWU_PROTOCOL_VERSION_MAJOR;
+	result->version_minor = FWU_PROTOCOL_VERSION_MINOR;
+	result->max_payload_size = agent->max_payload_size;
+	result->flags = FWU_FLAG_PARTIAL_UPDATE;
+	result->vendor_specific_flags = 0;
+
+	return FWU_STATUS_SUCCESS;
+}
+
+static int begin_staging(void *context, uint32_t vendor_flags, uint32_t partial_update_count,
+			 const struct uuid_octets *update_guid)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	int result = FWU_STATUS_DENIED;
+	uint32_t i = 0;
+
+	switch (agent->state) {
+	case staging:
+		/* Discard pending state */
+		result = cancel_staging(context);
+		if (result != FWU_STATUS_SUCCESS)
+			goto error;
+
+		result = clean(context);
+		if (result != FWU_STATUS_SUCCESS)
+			return result;
+
+		/* fallthrough */
+
+	case regular:
+		if (partial_update_count) {
+			/* Put selected images into staging state */
+			for (i = 0; i < partial_update_count; i++) {
+				struct psa_fwu_m_image *image = NULL;
+
+				image = find_image(agent, &update_guid[i]);
+				if (!image)
+					goto error;
+
+				/* Deny explicitly asked read-only images */
+				if (!image->write)
+					goto error;
+
+				psa_status = psa_fwu_start(image->component, NULL, 0);
+				if (psa_status != PSA_SUCCESS)
+					goto error;
+
+				image->selected_for_staging = true;
+			}
+		} else {
+			/* Put all images into staging state */
+			for (i = 0; i < agent->image_count; i++) {
+				struct psa_fwu_m_image *image = &agent->images[i];
+
+				/* Skip read-only images */
+				if (!image->write)
+					continue;
+
+				psa_status = psa_fwu_start(image->component, NULL, 0);
+				if (psa_status != PSA_SUCCESS)
+					goto error;
+
+				image->selected_for_staging = true;
+			}
+		}
+
+		set_agent_state(agent, staging);
+
+		return FWU_STATUS_SUCCESS;
+
+	default:
+		/* Calling begin_staging in other states is deined */
+		return FWU_STATUS_DENIED;
+	}
+
+error:
+	/* Revert everything to regular state */
+	result = clean(context);
+	if (result != FWU_STATUS_SUCCESS)
+		return result;
+
+	return FWU_STATUS_UNKNOWN;
+}
+
+static int end_staging(void *context)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	struct psa_fwu_m_image *image = NULL;
+	bool all_images_accepted = true;
+	size_t i = 0;
+
+	if (agent->state != staging)
+		return FWU_STATUS_DENIED;
+
+	/* Check if there are open image handles */
+	for (i = 0; i < ARRAY_SIZE(agent->handles); i++)
+		if (agent->handles[i].used)
+			return FWU_STATUS_BUSY;
+
+	/* Finish images which were selected for staging */
+	for (i = 0; i < agent->image_count; i++) {
+		image = &agent->images[i];
+
+		if (!image->selected_for_staging)
+			continue;
+
+		psa_status = psa_fwu_finish(image->component);
+		if (psa_status != PSA_SUCCESS)
+			return psa_status_to_fwu_status(psa_status);
+
+		if (!image->accepted)
+			all_images_accepted = false;
+	}
+
+	/* Invoke install step */
+	psa_status = psa_fwu_install();
+	if (psa_status != PSA_SUCCESS)
+		return psa_status_to_fwu_status(psa_status);
+
+	if (all_images_accepted) {
+		/* If all images are accepted then accept the update and jump to regular state */
+		psa_status = psa_fwu_accept();
+		if (psa_status != PSA_SUCCESS)
+			return psa_status_to_fwu_status(psa_status);
+
+		set_agent_state(agent, regular);
+	} else {
+		/* There are images which are not accepted, switch to trial state */
+		set_agent_state(agent, trial);
+	}
+
+	return FWU_STATUS_SUCCESS;
+}
+
+static int cancel_staging(void *context)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	size_t i = 0;
+
+	if (agent->state != staging)
+		return FWU_STATUS_DENIED;
+
+	/* Close all images */
+	for (i = 0; i < ARRAY_SIZE(agent->handles); i++)
+		free_handle(&agent->handles[i]);
+
+	/* Cancel all images */
+	for (i = 0; i < agent->image_count; i++) {
+		struct psa_fwu_m_image *image = &agent->images[i];
+
+		if (!image->selected_for_staging)
+			continue;
+
+		psa_status = psa_fwu_cancel(image->component);
+		if (psa_status != PSA_SUCCESS)
+			return psa_status_to_fwu_status(psa_status);
+
+		image->selected_for_staging = false;
+		image->accepted = false;
+	}
+
+	set_agent_state(agent, regular);
+
+	return FWU_STATUS_SUCCESS;
+}
+
+static int open(void *context, const struct uuid_octets *uuid, uint8_t op_type, uint32_t *handle)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	struct psa_fwu_m_image *image = NULL;
+
+	/* Write operation is only allowed in staging state */
+	if (op_type == FWU_OP_TYPE_WRITE && agent->state != staging)
+		return FWU_STATUS_DENIED;
+
+	image = find_image(agent, uuid);
+	if (!image)
+		return FWU_STATUS_UNKNOWN;
+
+	/* Check if the image was selected for staging of opening for write */
+	if (op_type == FWU_OP_TYPE_WRITE && !image->selected_for_staging)
+		return FWU_STATUS_DENIED;
+
+	/* Check if the image supports the required operation type */
+	if ((op_type == FWU_OP_TYPE_READ && !image->read) ||
+	    (op_type == FWU_OP_TYPE_WRITE && !image->write))
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	*handle = allocate_handle(agent, image, op_type);
+	if (*handle == FWU_INVALID_HANDLE)
+		return FWU_STATUS_NOT_AVAILABLE;
+
+	return FWU_STATUS_SUCCESS;
+}
+
+static int write_stream(void *context, uint32_t handle, const uint8_t *data, size_t data_len)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	struct psa_fwu_m_handle *handle_desc = NULL;
+	int result = FWU_STATUS_DENIED;
+	size_t offset_after_write = 0;
+
+	if (agent->state != staging)
+		return FWU_STATUS_DENIED;
+
+	handle_desc = get_handle(agent, handle);
+	if (!handle_desc)
+		return FWU_STATUS_UNKNOWN;
+
+	if (handle_desc->op_type != FWU_OP_TYPE_WRITE)
+		return FWU_STATUS_NO_PERMISSION;
+
+	if (ADD_OVERFLOW(handle_desc->current_offset, data_len, &offset_after_write))
+		return FWU_STATUS_OUT_OF_BOUNDS;
+
+	if (!handle_desc->image->selected_for_staging || !handle_desc->image->write)
+		return FWU_STATUS_DENIED; /* LCOV_EXCL_LINE */
+
+	result = handle_desc->image->write(agent, handle_desc->image, handle_desc->current_offset,
+					   data, data_len);
+	if (result != FWU_STATUS_SUCCESS)
+		return result;
+
+	handle_desc->current_offset = offset_after_write;
+
+	return FWU_STATUS_SUCCESS;
+}
+
+static int read_stream(void *context, uint32_t handle, uint8_t *buf, size_t buf_size,
+		       size_t *read_len, size_t *total_len)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	struct psa_fwu_m_handle *handle_desc = NULL;
+
+	handle_desc = get_handle(agent, handle);
+	if (!handle_desc)
+		return FWU_STATUS_UNKNOWN;
+
+	if (handle_desc->op_type != FWU_OP_TYPE_READ)
+		return FWU_STATUS_NO_PERMISSION;
+
+	if (!handle_desc->image->read)
+		return FWU_STATUS_DENIED; /* LCOV_EXCL_LINE */
+
+	return handle_desc->image->read(agent, handle_desc->image, buf, buf_size, read_len,
+					total_len);
+}
+
+static int commit(void *context, uint32_t handle, bool accepted, uint32_t max_atomic_len,
+		  uint32_t *progress, uint32_t *total_work)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	struct psa_fwu_m_handle *handle_desc = NULL;
+
+	handle_desc = get_handle(agent, handle);
+	if (!handle_desc)
+		return FWU_STATUS_UNKNOWN;
+
+	if (handle_desc->image->selected_for_staging)
+		handle_desc->image->accepted = accepted;
+
+	free_handle(handle_desc);
+
+	*progress = 1;
+	*total_work = 1;
+
+	return FWU_STATUS_SUCCESS;
+}
+
+static int accept(void *context, const struct uuid_octets *image_type_uuid)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	struct psa_fwu_m_image *image = NULL;
+	size_t i = 0;
+
+	if (agent->state != trial)
+		return FWU_STATUS_DENIED;
+
+	image = find_image(agent, image_type_uuid);
+	if (!image)
+		return FWU_STATUS_UNKNOWN;
+
+	if (!image->selected_for_staging)
+		return FWU_STATUS_DENIED;
+
+	image->accepted = true;
+
+	/* Accept update if all images has been accepted */
+	for (i = 0; i < agent->image_count; i++) {
+		image = &agent->images[i];
+
+		if (!image->selected_for_staging)
+			continue;
+
+		if (!image->accepted)
+			return FWU_STATUS_SUCCESS;
+	}
+
+	psa_status = psa_fwu_accept();
+	if (psa_status != PSA_SUCCESS)
+		return psa_status_to_fwu_status(psa_status);
+
+	set_agent_state(agent, regular);
+
+	return FWU_STATUS_SUCCESS;
+}
+
+static int select_previous(void *context)
+{
+	struct psa_fwu_m_update_agent *agent = (struct psa_fwu_m_update_agent *)context;
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+
+	if (agent->state != trial)
+		return FWU_STATUS_DENIED;
+
+	psa_status = psa_fwu_reject(0);
+	if (psa_status != PSA_SUCCESS)
+		return psa_status_to_fwu_status(psa_status);
+
+	set_agent_state(agent, regular);
+
+	return FWU_STATUS_SUCCESS;
+}
+
+static const struct update_agent_interface interface = {
+	.discover = discover,
+	.begin_staging = begin_staging,
+	.end_staging = end_staging,
+	.cancel_staging = cancel_staging,
+	.open = open,
+	.write_stream = write_stream,
+	.read_stream = read_stream,
+	.commit = commit,
+	.accept_image = accept,
+	.select_previous = select_previous,
+};
+
+struct update_agent *psa_fwu_m_update_agent_init(
+	const struct psa_fwu_m_image_mapping image_mapping[], size_t image_count,
+	uint32_t max_payload_size)
+{
+	struct psa_fwu_m_update_agent *context = NULL;
+	struct psa_fwu_m_image *images = NULL;
+	struct update_agent *agent = NULL;
+	size_t i = 0;
+
+	/* Allocate +1 image for the Image directory */
+	images = (struct psa_fwu_m_image *)calloc(image_count + 1, sizeof(*images));
+	if (!images)
+		return NULL; /* LCOV_EXCL_LINE */
+
+	context = (struct psa_fwu_m_update_agent *)calloc(1, sizeof(*context));
+	if (!context) {
+		/* LCOV_EXCL_START */
+		free(images);
+		return NULL;
+		/* LCOV_EXCL_STOP */
+	}
+
+	agent = (struct update_agent *)calloc(1, sizeof(*agent));
+	if (!agent) {
+		/* LCOV_EXCL_START */
+		free(images);
+		free(context);
+		return NULL;
+		/* LCOV_EXCL_STOP */
+	}
+
+	for (i = 0; i < image_count; i++) {
+		images[i].uuid = image_mapping[i].uuid;
+		images[i].component = image_mapping[i].component;
+		images[i].selected_for_staging = false;
+		images[i].read = NULL; /* Cannot read images */
+		images[i].write = image_write;
+	}
+
+	/* Insert Image directory as the last image */
+	uuid_octets_from_canonical(&images[image_count].uuid, FWU_DIRECTORY_CANONICAL_UUID);
+	images[image_count].component = 0;
+	images[image_count].selected_for_staging = false;
+	images[i].read = image_directory_read;
+	images[i].write = NULL; /* Cannot write Images directory */
+
+	context->images = images;
+	context->image_count = image_count + 1;
+	context->max_payload_size = max_payload_size;
+	context->state = regular;
+
+	agent->context = context;
+	agent->interface = &interface;
+
+	return agent;
+}
+
+void psa_fwu_m_update_agent_deinit(struct update_agent *update_agent)
+{
+	struct psa_fwu_m_update_agent *context =
+		(struct psa_fwu_m_update_agent *)update_agent->context;
+
+	free(context->images);
+	free(context);
+	free(update_agent);
+}
diff --git a/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.h b/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.h
new file mode 100644
index 0000000..3c06570
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef PSA_FWU_M_UPDATE_AGENT_H
+#define PSA_FWU_M_UPDATE_AGENT_H
+
+#include "service/fwu/common/update_agent_interface.h"
+#include "service/fwu/psa_fwu_m/interface/update.h"
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct psa_fwu_m_image_mapping {
+	struct uuid_octets uuid;
+	psa_fwu_component_t component;
+};
+
+/**
+ * \brief Initialise the PSA FWU M update_agent
+ *
+ * \param[in]  image_mapping    Component mapping array
+ * \param[in]  image_count      Component mapping count
+ * \param[in]  max_payload_size The maximum number of bytes that a payload can contain
+ *
+ * \return  The update_agent
+ */
+struct update_agent *psa_fwu_m_update_agent_init(
+	const struct psa_fwu_m_image_mapping image_mapping[], size_t image_count,
+	uint32_t max_payload_size);
+
+/**
+ * \brief De-initialise the update agent
+ *
+ * \param[in]  update_agent    The subject update_agent
+ */
+void psa_fwu_m_update_agent_deinit(struct update_agent *update_agent);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_FWU_M_UPDATE_AGENT_H */
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/service/fwu/psa_fwu_m/agent/test/component.cmake
similarity index 72%
copy from components/service/fwu/provider/serializer/packed-c/component.cmake
copy to components/service/fwu/psa_fwu_m/agent/test/component.cmake
index 4209cae..9ba929f 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/service/fwu/psa_fwu_m/agent/test/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
-	)
+	"${CMAKE_CURRENT_LIST_DIR}/test_psa_fwu_m_update_agent.cpp"
+)
diff --git a/components/service/fwu/psa_fwu_m/agent/test/test_psa_fwu_m_update_agent.cpp b/components/service/fwu/psa_fwu_m/agent/test/test_psa_fwu_m_update_agent.cpp
new file mode 100644
index 0000000..de289ff
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/agent/test/test_psa_fwu_m_update_agent.cpp
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "../psa_fwu_m_update_agent.h"
+#include "service/fwu/psa_fwu_m/interface/mock/mock_psa_fwu_m.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include <string.h>
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
+TEST_GROUP(psa_fwu_m_update_agent) {
+	TEST_SETUP() {
+		agent = psa_fwu_m_update_agent_init(mapping, 2, 4096);
+		handle = 0;
+		progress = 0;
+		total_work = 0;
+	}
+
+	TEST_TEARDOWN() {
+		psa_fwu_m_update_agent_deinit(agent);
+
+		mock().checkExpectations();
+		mock().clear();
+	}
+
+	void begin_staging() {
+		expect_mock_psa_fwu_start(mapping[0].component, NULL, 0, PSA_SUCCESS);
+		expect_mock_psa_fwu_start(mapping[1].component, NULL, 0, PSA_SUCCESS);
+		LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_begin_staging(agent, 0, 0, NULL));
+	}
+
+	void end_staging() {
+		expect_mock_psa_fwu_finish(mapping[0].component, PSA_SUCCESS);
+		expect_mock_psa_fwu_finish(mapping[1].component, PSA_SUCCESS);
+
+		expect_mock_psa_fwu_install(PSA_SUCCESS);
+
+		LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_end_staging(agent));
+	}
+
+	void open() {
+		LONGS_EQUAL(FWU_STATUS_SUCCESS,
+			    update_agent_open(agent, &mapping[0].uuid, FWU_OP_TYPE_WRITE, &handle));
+	}
+
+	void write(const uint8_t *data, size_t data_len) {
+		expect_mock_psa_fwu_write(mapping[0].component, 0, NULL, 0, PSA_SUCCESS);
+		LONGS_EQUAL(FWU_STATUS_SUCCESS,
+			    update_agent_write_stream(agent, handle, data, data_len));
+	}
+
+	struct update_agent *agent;
+	uint32_t handle;
+	uint32_t progress;
+	uint32_t total_work;
+
+	const psa_fwu_m_image_mapping mapping[2] = {
+		{
+			.uuid = {
+				0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+				0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
+			},
+			.component = 3
+		},
+		{
+			.uuid = {
+				0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
+				0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
+			},
+			.component = 2
+		},
+	};
+
+	const struct uuid_octets image_directory_uuid = {
+		0xde, 0xee, 0x58, 0xd9, 0x51, 0x47, 0x4a, 0xd3,
+		0xa2, 0x90, 0x77, 0x66, 0x6e, 0x23, 0x41, 0xa5
+	};
+};
+
+TEST(psa_fwu_m_update_agent, discover)
+{
+	fwu_discovery_result result = { 0 };
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_discover(agent, &result));
+
+	UNSIGNED_LONGS_EQUAL(0, result.service_status);
+	UNSIGNED_LONGS_EQUAL(1, result.version_major);
+	UNSIGNED_LONGS_EQUAL(0, result.version_minor);
+	UNSIGNED_LONGS_EQUAL(1, result.flags);
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_start_fail)
+{
+	expect_mock_psa_fwu_start(mapping[0].component, NULL, 0, PSA_ERROR_GENERIC_ERROR);
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_clean(mapping[1].component, PSA_SUCCESS);
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_begin_staging(agent, 0, 0, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_start_and_clean_fail)
+{
+	expect_mock_psa_fwu_start(mapping[0].component, NULL, 0, PSA_ERROR_GENERIC_ERROR);
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_ERROR_GENERIC_ERROR);
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_begin_staging(agent, 0, 0, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_partial_invalid_uuid)
+{
+	const struct uuid_octets update_guid = { 0 };
+
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_clean(mapping[1].component, PSA_SUCCESS);
+
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_begin_staging(agent, 0, 1, &update_guid));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_partial_image_directory_uuid)
+{
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_clean(mapping[1].component, PSA_SUCCESS);
+
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_begin_staging(agent, 0, 1, &image_directory_uuid));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_partial_start_fail)
+{
+	expect_mock_psa_fwu_start(mapping[0].component, NULL, 0, PSA_ERROR_GENERIC_ERROR);
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_clean(mapping[1].component, PSA_SUCCESS);
+
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_begin_staging(agent, 0, 1, &mapping[0].uuid));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_partial_start_and_clean_fail)
+{
+	expect_mock_psa_fwu_start(mapping[0].component, NULL, 0, PSA_ERROR_GENERIC_ERROR);
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_ERROR_GENERIC_ERROR);
+
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_begin_staging(agent, 0, 1, &mapping[0].uuid));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_partial)
+{
+	expect_mock_psa_fwu_start(mapping[0].component, NULL, 0, PSA_SUCCESS);
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_begin_staging(agent, 0, 1, &mapping[0].uuid));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging)
+{
+	begin_staging();
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_repeated_cancel_fail)
+{
+	begin_staging();
+
+	expect_mock_psa_fwu_cancel(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_cancel(mapping[1].component, PSA_ERROR_GENERIC_ERROR);
+
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_clean(mapping[1].component, PSA_SUCCESS);
+
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_begin_staging(agent, 0, 0, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_repeated_clean_fail)
+{
+	begin_staging();
+
+	expect_mock_psa_fwu_cancel(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_cancel(mapping[1].component, PSA_SUCCESS);
+
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_ERROR_GENERIC_ERROR);
+
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_begin_staging(agent, 0, 0, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_repeated)
+{
+	begin_staging();
+
+	expect_mock_psa_fwu_cancel(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_cancel(mapping[1].component, PSA_SUCCESS);
+
+	expect_mock_psa_fwu_clean(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_clean(mapping[1].component, PSA_SUCCESS);
+
+	expect_mock_psa_fwu_start(mapping[0].component, NULL, 0, PSA_SUCCESS);
+	expect_mock_psa_fwu_start(mapping[1].component, NULL, 0, PSA_SUCCESS);
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_begin_staging(agent, 0, 0, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, begin_staging_in_trial_state)
+{
+	begin_staging();
+	end_staging();
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_begin_staging(agent, 0, 0, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, end_staging_not_in_staging)
+{
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_end_staging(agent));
+}
+
+TEST(psa_fwu_m_update_agent, end_staging_finish_fail)
+{
+	begin_staging();
+
+	expect_mock_psa_fwu_finish(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_finish(mapping[1].component, PSA_ERROR_GENERIC_ERROR);
+
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_end_staging(agent));
+}
+
+TEST(psa_fwu_m_update_agent, end_staging_install_fail)
+{
+	begin_staging();
+
+	expect_mock_psa_fwu_finish(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_finish(mapping[1].component, PSA_SUCCESS);
+
+	expect_mock_psa_fwu_install(PSA_ERROR_GENERIC_ERROR);
+
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_end_staging(agent));
+}
+
+TEST(psa_fwu_m_update_agent, end_staging)
+{
+	begin_staging();
+	end_staging();
+
+	// In trial state, so a repeated begin_staging should not succeed
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_begin_staging(agent, 0, 0, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, end_staging_with_opened_handles)
+{
+	begin_staging();
+	open();
+
+	LONGS_EQUAL(FWU_STATUS_BUSY, update_agent_end_staging(agent));
+}
+
+TEST(psa_fwu_m_update_agent, end_staging_all_accepted_accept_fail)
+{
+	begin_staging();
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &mapping[0].uuid, FWU_OP_TYPE_WRITE, &handle));
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_commit(agent, handle, true, 0, &progress, &total_work));
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &mapping[1].uuid, FWU_OP_TYPE_WRITE, &handle));
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_commit(agent, handle, true, 0, &progress, &total_work));
+
+	expect_mock_psa_fwu_finish(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_finish(mapping[1].component, PSA_SUCCESS);
+
+	expect_mock_psa_fwu_install(PSA_SUCCESS);
+
+	expect_mock_psa_fwu_accept(PSA_ERROR_GENERIC_ERROR);
+
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_end_staging(agent));
+}
+
+TEST(psa_fwu_m_update_agent, end_staging_all_accepted)
+{
+	begin_staging();
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &mapping[0].uuid, FWU_OP_TYPE_WRITE, &handle));
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_commit(agent, handle, true, 0, &progress, &total_work));
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &mapping[1].uuid, FWU_OP_TYPE_WRITE, &handle));
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_commit(agent, handle, true, 0, &progress, &total_work));
+
+	expect_mock_psa_fwu_accept(PSA_SUCCESS);
+	end_staging();
+
+	// In regular state, repeated begin_staging should succeed
+	begin_staging();
+}
+
+TEST(psa_fwu_m_update_agent, cancel_staging_not_in_staging)
+{
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_cancel_staging(agent));
+}
+
+TEST(psa_fwu_m_update_agent, cancel_staging_cancel_fail)
+{
+	begin_staging();
+
+	expect_mock_psa_fwu_cancel(mapping[0].component, PSA_ERROR_GENERIC_ERROR);
+
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_cancel_staging(agent));
+}
+
+TEST(psa_fwu_m_update_agent, cancel_staging)
+{
+	begin_staging();
+
+	expect_mock_psa_fwu_cancel(mapping[0].component, PSA_SUCCESS);
+	expect_mock_psa_fwu_cancel(mapping[1].component, PSA_SUCCESS);
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_cancel_staging(agent));
+}
+
+TEST(psa_fwu_m_update_agent, open_for_write_not_staging)
+{
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_open(agent, &mapping[0].uuid,
+		    FWU_OP_TYPE_WRITE, &handle));
+}
+
+
+TEST(psa_fwu_m_update_agent, open_for_write_uuid_not_exists)
+{
+	const struct uuid_octets uuid = { 0 };
+
+	begin_staging();
+
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_open(agent, &uuid, FWU_OP_TYPE_WRITE,
+							  &handle));
+}
+
+TEST(psa_fwu_m_update_agent, open_for_write_image_directory)
+{
+	begin_staging();
+
+	LONGS_EQUAL(FWU_STATUS_DENIED,
+		    update_agent_open(agent, &image_directory_uuid, FWU_OP_TYPE_WRITE, &handle));
+}
+
+TEST(psa_fwu_m_update_agent, open_for_write_partial_not_staging)
+{
+	expect_mock_psa_fwu_start(mapping[0].component, NULL, 0, PSA_SUCCESS);
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_begin_staging(agent, 0, 1, &mapping[0].uuid));
+
+	LONGS_EQUAL(FWU_STATUS_DENIED,
+		    update_agent_open(agent, &mapping[1].uuid, FWU_OP_TYPE_WRITE, &handle));
+}
+
+TEST(psa_fwu_m_update_agent, open_for_read)
+{
+	begin_staging();
+
+	LONGS_EQUAL(FWU_STATUS_NOT_AVAILABLE,
+		    update_agent_open(agent, &mapping[0].uuid, FWU_OP_TYPE_READ, &handle));
+}
+
+TEST(psa_fwu_m_update_agent, open)
+{
+	begin_staging();
+	open();
+}
+
+TEST(psa_fwu_m_update_agent, open_too_many)
+{
+	begin_staging();
+
+	while (1) {
+		int result = FWU_STATUS_DENIED;
+
+		result = update_agent_open(agent, &mapping[0].uuid, FWU_OP_TYPE_WRITE, &handle);
+		if (result == FWU_STATUS_NOT_AVAILABLE) {
+			break;
+		} else {
+			LONGS_EQUAL(FWU_STATUS_SUCCESS, result);
+		}
+	}
+}
+
+TEST(psa_fwu_m_update_agent, write_stream_not_in_staging)
+{
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_write_stream(agent, 0, NULL, 0));
+}
+
+TEST(psa_fwu_m_update_agent, write_stream_invalid_handle)
+{
+	begin_staging();
+
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_write_stream(agent, 0, NULL, 0));
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_write_stream(agent, 0xffffffff, NULL, 0));
+}
+
+TEST(psa_fwu_m_update_agent, write_stream_opened_for_read)
+{
+	begin_staging();
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &image_directory_uuid, FWU_OP_TYPE_READ, &handle));
+	LONGS_EQUAL(FWU_STATUS_NO_PERMISSION, update_agent_write_stream(agent, handle, NULL, 0));
+}
+
+TEST(psa_fwu_m_update_agent, write_stream_write_fail)
+{
+	begin_staging();
+	open();
+
+	expect_mock_psa_fwu_write(mapping[0].component, 0, NULL, 0, PSA_ERROR_GENERIC_ERROR);
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_write_stream(agent, handle, NULL, 0));
+}
+
+TEST(psa_fwu_m_update_agent, write_stream_overflow)
+{
+	uint8_t data[8];
+
+	memset(data, 0x5a, sizeof(data));
+
+	begin_staging();
+	open();
+
+	expect_mock_psa_fwu_write(mapping[0].component, 0, data, sizeof(data), PSA_SUCCESS);
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_write_stream(agent, handle, data, sizeof(data)));
+
+	LONGS_EQUAL(FWU_STATUS_OUT_OF_BOUNDS,
+		    update_agent_write_stream(agent, handle, NULL, 0xffffffffffffffff));
+}
+
+TEST(psa_fwu_m_update_agent, write_stream)
+{
+	uint8_t data[8];
+
+	memset(data, 0x5a, sizeof(data));
+
+	begin_staging();
+	open();
+
+	expect_mock_psa_fwu_write(mapping[0].component, 0, data, sizeof(data), PSA_SUCCESS);
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_write_stream(agent, handle, data, sizeof(data)));
+
+	expect_mock_psa_fwu_write(mapping[0].component, sizeof(data), data, sizeof(data), PSA_SUCCESS);
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_write_stream(agent, handle, data, sizeof(data)));
+}
+
+TEST(psa_fwu_m_update_agent, read_stream_invalid_handle)
+{
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_read_stream(agent, 0, NULL, 0, NULL, NULL));
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN,
+		    update_agent_read_stream(agent, 0xffffffff, NULL, 0, NULL, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, read_stream_opened_for_write)
+{
+	begin_staging();
+	open();
+
+	LONGS_EQUAL(FWU_STATUS_NO_PERMISSION,
+		    update_agent_read_stream(agent, handle, NULL, 0, NULL, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, read_image_directory_too_short)
+{
+	const size_t expected_len = sizeof(fwu_image_directory) + 2 * sizeof(fwu_image_info_entry);
+	size_t read_len = 0;
+	size_t total_len = 0;
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &image_directory_uuid, FWU_OP_TYPE_READ, &handle));
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_read_stream(agent, handle, NULL, 0, &read_len, &total_len));
+
+	UNSIGNED_LONGS_EQUAL(0, read_len);
+	UNSIGNED_LONGS_EQUAL(expected_len, total_len);
+}
+
+TEST(psa_fwu_m_update_agent, read_image_directory_query_fail)
+{
+	const size_t expected_len = sizeof(fwu_image_directory) + 2 * sizeof(fwu_image_info_entry);
+	uint8_t buffer[expected_len] = { 0 };
+	psa_fwu_component_info_t info = { 0 };
+	size_t read_len = 0;
+	size_t total_len = 0;
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &image_directory_uuid, FWU_OP_TYPE_READ, &handle));
+
+	expect_mock_psa_fwu_query(mapping[0].component, &info, PSA_ERROR_GENERIC_ERROR);
+	LONGS_EQUAL(FWU_STATUS_DENIED,
+		    update_agent_read_stream(agent, handle, buffer, sizeof(buffer), &read_len,
+		    			     &total_len));
+
+	UNSIGNED_LONGS_EQUAL(0, read_len);
+	UNSIGNED_LONGS_EQUAL(expected_len, total_len);
+}
+
+TEST(psa_fwu_m_update_agent, read_image_directory)
+{
+	const size_t expected_len = sizeof(fwu_image_directory) + 2 * sizeof(fwu_image_info_entry);
+	uint8_t buffer[expected_len] = { 0 };
+	psa_fwu_component_info_t info0 = {
+		.state = PSA_FWU_REJECTED,
+		.version = {.major = 1, .minor = 2, .patch = 3},
+		.max_size = 123,
+
+	};
+	psa_fwu_component_info_t info1 = {
+		.state = PSA_FWU_UPDATED,
+		.version = {.major = 6, .minor = 7, .patch = 8},
+		.max_size = 456,
+	};
+	size_t read_len = 0;
+	size_t total_len = 0;
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &image_directory_uuid, FWU_OP_TYPE_READ, &handle));
+
+	expect_mock_psa_fwu_query(mapping[0].component, &info0, PSA_SUCCESS);
+	expect_mock_psa_fwu_query(mapping[1].component, &info1, PSA_SUCCESS);
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_read_stream(agent, handle, buffer, sizeof(buffer), &read_len,
+		    			     &total_len));
+
+	UNSIGNED_LONGS_EQUAL(expected_len, read_len);
+	UNSIGNED_LONGS_EQUAL(expected_len, total_len);
+
+	struct fwu_image_directory *directory = (struct fwu_image_directory *)buffer;
+	UNSIGNED_LONGS_EQUAL(2, directory->directory_version);
+	UNSIGNED_LONGS_EQUAL(0x18, directory->img_info_offset);
+	UNSIGNED_LONGS_EQUAL(2, directory->num_images);
+	UNSIGNED_LONGS_EQUAL(0, directory->correct_boot);
+	UNSIGNED_LONGS_EQUAL(0x28, directory->img_info_size);
+
+	MEMCMP_EQUAL(&mapping[0].uuid, directory->img_info_entry[0].img_type_uuid,
+		     sizeof(mapping[0].uuid));
+	UNSIGNED_LONGS_EQUAL(1, directory->img_info_entry[0].client_permissions);
+	UNSIGNED_LONGS_EQUAL(info0.max_size, directory->img_info_entry[0].img_max_size);
+	UNSIGNED_LONGS_EQUAL(0, directory->img_info_entry[0].lowest_accepted_version);
+	UNSIGNED_LONGLONGS_EQUAL(0x01020003, directory->img_info_entry[0].img_version);
+	UNSIGNED_LONGS_EQUAL(0, directory->img_info_entry[0].accepted);
+	UNSIGNED_LONGS_EQUAL(0, directory->img_info_entry[0].reserved);
+
+	MEMCMP_EQUAL(&mapping[1].uuid, directory->img_info_entry[1].img_type_uuid,
+		     sizeof(mapping[1].uuid));
+	UNSIGNED_LONGS_EQUAL(1, directory->img_info_entry[1].client_permissions);
+	UNSIGNED_LONGS_EQUAL(info1.max_size, directory->img_info_entry[1].img_max_size);
+	UNSIGNED_LONGS_EQUAL(0, directory->img_info_entry[1].lowest_accepted_version);
+	UNSIGNED_LONGLONGS_EQUAL(0x06070008, directory->img_info_entry[1].img_version);
+	UNSIGNED_LONGS_EQUAL(1, directory->img_info_entry[1].accepted);
+	UNSIGNED_LONGS_EQUAL(0, directory->img_info_entry[1].reserved);
+}
+
+TEST(psa_fwu_m_update_agent, commit_invalid_handle)
+{
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_commit(agent, 0, false, 0, &progress,
+							    &total_work));
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_commit(agent, 0xffffffff, false, 0, &progress,
+							    &total_work));
+}
+
+TEST(psa_fwu_m_update_agent, commit_read)
+{
+	LONGS_EQUAL(FWU_STATUS_SUCCESS,
+		    update_agent_open(agent, &image_directory_uuid, FWU_OP_TYPE_READ, &handle));
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_commit(agent, handle, false, 0, &progress,
+							    &total_work));
+}
+
+TEST(psa_fwu_m_update_agent, commit_write)
+{
+	begin_staging();
+	open();
+
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_commit(agent, handle, false, 0, &progress,
+							    &total_work));
+}
+
+TEST(psa_fwu_m_update_agent, accept_image_not_in_trial)
+{
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_accept_image(agent, NULL));
+}
+
+TEST(psa_fwu_m_update_agent, accept_image_invalid_uuid)
+{
+	struct uuid_octets uuid = { 0 };
+
+	begin_staging();
+	end_staging();
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_accept_image(agent, &uuid));
+}
+
+TEST(psa_fwu_m_update_agent, accept_image_not_selected)
+{
+	begin_staging();
+	end_staging();
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_accept_image(agent, &image_directory_uuid));
+}
+
+TEST(psa_fwu_m_update_agent, accept_image_one)
+{
+	begin_staging();
+	end_staging();
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_accept_image(agent, &mapping[0].uuid));
+}
+
+TEST(psa_fwu_m_update_agent, accept_image_accept_fail)
+{
+	begin_staging();
+	end_staging();
+
+	expect_mock_psa_fwu_accept(PSA_ERROR_GENERIC_ERROR);
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_accept_image(agent, &mapping[0].uuid));
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_accept_image(agent, &mapping[1].uuid));
+}
+
+TEST(psa_fwu_m_update_agent, accept_image)
+{
+	begin_staging();
+	end_staging();
+
+	expect_mock_psa_fwu_accept(PSA_SUCCESS);
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_accept_image(agent, &mapping[0].uuid));
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_accept_image(agent, &mapping[1].uuid));
+}
+
+
+TEST(psa_fwu_m_update_agent, select_previous_not_in_trial)
+{
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_select_previous(agent));
+}
+
+TEST(psa_fwu_m_update_agent, select_previous_reject_fail)
+{
+	/* This test also covers error code conversion */
+	begin_staging();
+	end_staging();
+
+	expect_mock_psa_fwu_reject(0, PSA_ERROR_DOES_NOT_EXIST);
+	LONGS_EQUAL(FWU_STATUS_UNKNOWN, update_agent_select_previous(agent));
+
+	expect_mock_psa_fwu_reject(0, PSA_ERROR_INVALID_ARGUMENT);
+	LONGS_EQUAL(FWU_STATUS_OUT_OF_BOUNDS, update_agent_select_previous(agent));
+
+
+	expect_mock_psa_fwu_reject(0, PSA_ERROR_INVALID_SIGNATURE);
+	LONGS_EQUAL(FWU_STATUS_AUTH_FAIL, update_agent_select_previous(agent));
+
+
+	expect_mock_psa_fwu_reject(0, PSA_ERROR_NOT_PERMITTED);
+	LONGS_EQUAL(FWU_STATUS_NO_PERMISSION, update_agent_select_previous(agent));
+
+
+	expect_mock_psa_fwu_reject(0, PSA_ERROR_BAD_STATE);
+	LONGS_EQUAL(FWU_STATUS_DENIED, update_agent_select_previous(agent));
+}
+
+TEST(psa_fwu_m_update_agent, select_previous)
+{
+	/* This test also covers error code conversion */
+	begin_staging();
+	end_staging();
+
+	expect_mock_psa_fwu_reject(0, PSA_SUCCESS);
+	LONGS_EQUAL(FWU_STATUS_SUCCESS, update_agent_select_previous(agent));
+}
\ No newline at end of file
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/service/fwu/psa_fwu_m/interface/mock/component.cmake
similarity index 72%
copy from components/service/fwu/provider/serializer/packed-c/component.cmake
copy to components/service/fwu/psa_fwu_m/interface/mock/component.cmake
index 4209cae..176a4aa 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/service/fwu/psa_fwu_m/interface/mock/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
-	)
+	"${CMAKE_CURRENT_LIST_DIR}/mock_psa_fwu_m.cpp"
+)
diff --git a/components/service/fwu/psa_fwu_m/interface/mock/mock_psa_fwu_m.cpp b/components/service/fwu/psa_fwu_m/interface/mock/mock_psa_fwu_m.cpp
new file mode 100644
index 0000000..fd24c55
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/interface/mock/mock_psa_fwu_m.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "mock_psa_fwu_m.h"
+#include <CppUTestExt/MockSupport.h>
+
+void expect_mock_psa_fwu_query(psa_fwu_component_t component, const psa_fwu_component_info_t *info,
+			       psa_status_t result)
+{
+	mock().
+		expectOneCall("psa_fwu_query").
+		withUnsignedIntParameter("component", component).
+		withOutputParameterReturning("info", info, sizeof(*info)).
+		andReturnValue(result);
+}
+
+psa_status_t psa_fwu_query(psa_fwu_component_t component, psa_fwu_component_info_t *info)
+{
+	return mock().
+		actualCall("psa_fwu_query").
+		withUnsignedIntParameter("component", component).
+		withOutputParameter("info", info).
+		returnIntValue();
+}
+
+void expect_mock_psa_fwu_start(psa_fwu_component_t component, const void *manifest,
+			       size_t manifest_size, psa_status_t result)
+{
+	mock().
+		expectOneCall("psa_fwu_start").
+		withUnsignedIntParameter("component", component).
+		withMemoryBufferParameter("manifest", (const uint8_t *)manifest, manifest_size).
+		withUnsignedIntParameter("manifest_size", manifest_size).
+		andReturnValue(result);
+}
+
+psa_status_t psa_fwu_start(psa_fwu_component_t component, const void *manifest,
+                           size_t manifest_size)
+{
+	return mock().
+		actualCall("psa_fwu_start").
+		withUnsignedIntParameter("component", component).
+		withMemoryBufferParameter("manifest", (const uint8_t *)manifest, manifest_size).
+		withUnsignedIntParameter("manifest_size", manifest_size).
+		returnIntValue();
+}
+
+void expect_mock_psa_fwu_write(psa_fwu_component_t component, size_t image_offset,
+			       void *block, size_t block_size, psa_status_t result)
+{
+	mock().
+		expectOneCall("psa_fwu_write").
+		withUnsignedIntParameter("image_offset", image_offset).
+		withMemoryBufferParameter("block", (const uint8_t *)block, block_size).
+		withUnsignedIntParameter("block_size", block_size).
+		andReturnValue(result);
+}
+
+psa_status_t psa_fwu_write(psa_fwu_component_t component, size_t image_offset, const void *block,
+                           size_t block_size)
+{
+	return mock().
+		actualCall("psa_fwu_write").
+		withUnsignedIntParameter("image_offset", image_offset).
+		withMemoryBufferParameter("block", (const uint8_t *)block, block_size).
+		withUnsignedIntParameter("block_size", block_size).
+		returnIntValue();
+}
+
+void expect_mock_psa_fwu_finish(psa_fwu_component_t component, psa_status_t result)
+{
+	mock().
+		expectOneCall("psa_fwu_finish").
+		withUnsignedIntParameter("component", component).
+		andReturnValue(result);
+}
+
+psa_status_t psa_fwu_finish(psa_fwu_component_t component)
+{
+	return mock().
+		actualCall("psa_fwu_finish").
+		withUnsignedIntParameter("component", component).
+		returnIntValue();
+}
+
+void expect_mock_psa_fwu_cancel(psa_fwu_component_t component, psa_status_t result)
+{
+	mock().
+		expectOneCall("psa_fwu_cancel").
+		withUnsignedIntParameter("component", component).
+		andReturnValue(result);
+}
+
+psa_status_t psa_fwu_cancel(psa_fwu_component_t component)
+{
+	return mock().
+		actualCall("psa_fwu_cancel").
+		withUnsignedIntParameter("component", component).
+		returnIntValue();
+}
+
+void expect_mock_psa_fwu_clean(psa_fwu_component_t component, psa_status_t result)
+{
+	mock().
+		expectOneCall("psa_fwu_clean").
+		withUnsignedIntParameter("component", component).
+		andReturnValue(result);
+}
+
+psa_status_t psa_fwu_clean(psa_fwu_component_t component)
+{
+	return mock().
+		actualCall("psa_fwu_clean").
+		withUnsignedIntParameter("component", component).
+		returnIntValue();
+}
+
+void expect_mock_psa_fwu_install(psa_status_t result)
+{
+	mock().expectOneCall("psa_fwu_install").andReturnValue(result);
+}
+
+psa_status_t psa_fwu_install(void)
+{
+	return mock().actualCall("psa_fwu_install").returnIntValue();
+}
+
+void expect_mock_psa_fwu_request_reboot(psa_status_t result)
+{
+	mock().expectOneCall("psa_fwu_request_reboot").andReturnValue(result);
+}
+
+psa_status_t psa_fwu_request_reboot(void)
+{
+	return mock().actualCall("psa_fwu_request_reboot").returnIntValue();
+}
+
+void expect_mock_psa_fwu_reject(psa_status_t error, psa_status_t result)
+{
+	mock().expectOneCall("psa_fwu_reject").withIntParameter("error", error).andReturnValue(result);
+}
+
+psa_status_t psa_fwu_reject(psa_status_t error)
+{
+	return mock().actualCall("psa_fwu_reject").withIntParameter("error", error).returnIntValue();
+}
+
+void expect_mock_psa_fwu_accept(psa_status_t result)
+{
+	mock().expectOneCall("psa_fwu_accept").andReturnValue(result);
+}
+
+psa_status_t psa_fwu_accept(void)
+{
+	return mock().actualCall("psa_fwu_accept").returnIntValue();
+}
\ No newline at end of file
diff --git a/components/service/fwu/psa_fwu_m/interface/mock/mock_psa_fwu_m.h b/components/service/fwu/psa_fwu_m/interface/mock/mock_psa_fwu_m.h
new file mode 100644
index 0000000..954f07c
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/interface/mock/mock_psa_fwu_m.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "../update.h"
+
+void expect_mock_psa_fwu_query(psa_fwu_component_t component, const psa_fwu_component_info_t *info,
+			       psa_status_t result);
+
+void expect_mock_psa_fwu_start(psa_fwu_component_t component, const void *manifest,
+			       size_t manifest_size, psa_status_t result);
+
+void expect_mock_psa_fwu_write(psa_fwu_component_t component, size_t image_offset,
+			       void *block, size_t block_size, psa_status_t result);
+
+void expect_mock_psa_fwu_finish(psa_fwu_component_t component, psa_status_t result);
+
+void expect_mock_psa_fwu_cancel(psa_fwu_component_t component, psa_status_t result);
+
+void expect_mock_psa_fwu_clean(psa_fwu_component_t component, psa_status_t result);
+
+void expect_mock_psa_fwu_install(psa_status_t result);
+
+void expect_mock_psa_fwu_request_reboot(psa_status_t result);
+
+void expect_mock_psa_fwu_reject(psa_status_t error, psa_status_t result);
+
+void expect_mock_psa_fwu_accept(psa_status_t result);
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/service/fwu/psa_fwu_m/interface/mock/test/component.cmake
similarity index 72%
copy from components/service/fwu/provider/serializer/packed-c/component.cmake
copy to components/service/fwu/psa_fwu_m/interface/mock/test/component.cmake
index 4209cae..8846b40 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/service/fwu/psa_fwu_m/interface/mock/test/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
-	)
+	"${CMAKE_CURRENT_LIST_DIR}/test_mock_psa_fwu_m.cpp"
+)
diff --git a/components/service/fwu/psa_fwu_m/interface/mock/test/test_mock_psa_fwu_m.cpp b/components/service/fwu/psa_fwu_m/interface/mock/test/test_mock_psa_fwu_m.cpp
new file mode 100644
index 0000000..b3287f2
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/interface/mock/test/test_mock_psa_fwu_m.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "../mock_psa_fwu_m.h"
+#include <string.h>
+#include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
+
+TEST_GROUP(mock_psa_fwu_m) {
+	TEST_TEARDOWN() {
+		mock().checkExpectations();
+		mock().clear();
+	}
+
+	const psa_fwu_component_t component = 0x5a;
+	const psa_status_t result = PSA_ERROR_GENERIC_ERROR;
+};
+
+TEST(mock_psa_fwu_m, query)
+{
+	psa_fwu_component_info_t expected_info = { 0 };
+	psa_fwu_component_info_t info = { 0 };
+
+	memset(&expected_info, 0x5a, sizeof(expected_info));
+
+	expect_mock_psa_fwu_query(component, &expected_info, result);
+	LONGS_EQUAL(result, psa_fwu_query(component, &info));
+	MEMCMP_EQUAL(&info, &expected_info, sizeof(info));
+}
+
+TEST(mock_psa_fwu_m, start)
+{
+	uint8_t manifest[8];
+
+	memset(manifest, 0x5a, sizeof(manifest));
+
+	expect_mock_psa_fwu_start(component, manifest, sizeof(manifest), result);
+	LONGS_EQUAL(result, psa_fwu_start(component, manifest, sizeof(manifest)));
+}
+
+TEST(mock_psa_fwu_m, start_null_manifest)
+{
+	expect_mock_psa_fwu_start(component, NULL, 0, result);
+	LONGS_EQUAL(result, psa_fwu_start(component, NULL, 0));
+}
+
+TEST(mock_psa_fwu_m, write)
+{
+	const size_t image_offset = 0x1000;
+	uint8_t block[8];
+
+	memset(block, 0x5a, sizeof(block));
+
+	expect_mock_psa_fwu_write(component, image_offset, block, sizeof(block), result);
+	LONGS_EQUAL(result, psa_fwu_write(component, image_offset, block, sizeof(block)));
+}
+
+TEST(mock_psa_fwu_m, finish)
+{
+	expect_mock_psa_fwu_finish(component, result);
+	LONGS_EQUAL(result, psa_fwu_finish(component));
+}
+
+TEST(mock_psa_fwu_m, cancel)
+{
+	expect_mock_psa_fwu_cancel(component, result);
+	LONGS_EQUAL(result, psa_fwu_cancel(component));
+}
+
+TEST(mock_psa_fwu_m, clean)
+{
+	expect_mock_psa_fwu_clean(component, result);
+	LONGS_EQUAL(result, psa_fwu_clean(component));
+}
+
+TEST(mock_psa_fwu_m, install)
+{
+	expect_mock_psa_fwu_install(result);
+	LONGS_EQUAL(result, psa_fwu_install());
+}
+
+TEST(mock_psa_fwu_m, request_reboot)
+{
+	expect_mock_psa_fwu_request_reboot(result);
+	LONGS_EQUAL(result, psa_fwu_request_reboot());
+}
+
+TEST(mock_psa_fwu_m, reject)
+{
+	psa_status_t error = PSA_ERROR_STORAGE_FAILURE;
+
+	expect_mock_psa_fwu_reject(error, result);
+	LONGS_EQUAL(result, psa_fwu_reject(error));
+}
+
+TEST(mock_psa_fwu_m, accept)
+{
+	expect_mock_psa_fwu_accept(result);
+	LONGS_EQUAL(result, psa_fwu_accept());
+}
diff --git a/components/service/fwu/provider/serializer/packed-c/component.cmake b/components/service/fwu/psa_fwu_m/interface/stub/component.cmake
similarity index 72%
rename from components/service/fwu/provider/serializer/packed-c/component.cmake
rename to components/service/fwu/psa_fwu_m/interface/stub/component.cmake
index 4209cae..a029460 100644
--- a/components/service/fwu/provider/serializer/packed-c/component.cmake
+++ b/components/service/fwu/psa_fwu_m/interface/stub/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,5 +9,5 @@
 endif()
 
 target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/packedc_fwu_provider_serializer.c"
-	)
+	"${CMAKE_CURRENT_LIST_DIR}/stub_psa_fwu_m.c"
+)
diff --git a/components/service/fwu/psa_fwu_m/interface/stub/stub_psa_fwu_m.c b/components/service/fwu/psa_fwu_m/interface/stub/stub_psa_fwu_m.c
new file mode 100644
index 0000000..bc9f8b7
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/interface/stub/stub_psa_fwu_m.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "../update.h"
+#include "protocols/service/fwu/status.h"
+
+psa_status_t psa_fwu_query(psa_fwu_component_t component, psa_fwu_component_info_t *info)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_start(psa_fwu_component_t component, const void *manifest,
+			   size_t manifest_size)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_write(psa_fwu_component_t component, size_t image_offset, const void *block,
+			   size_t block_size)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_finish(psa_fwu_component_t component)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_cancel(psa_fwu_component_t component)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_clean(psa_fwu_component_t component)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_install(void)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_request_reboot(void)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_reject(psa_status_t error)
+{
+	return FWU_STATUS_DENIED;
+}
+
+psa_status_t psa_fwu_accept(void)
+{
+	return FWU_STATUS_DENIED;
+}
diff --git a/components/service/fwu/psa_fwu_m/interface/tfm_fwu_defs.h b/components/service/fwu/psa_fwu_m/interface/tfm_fwu_defs.h
new file mode 100644
index 0000000..a940d1f
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/interface/tfm_fwu_defs.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef TFM_FWU_BOOTLOADER_DEFS_H
+#define TFM_FWU_BOOTLOADER_DEFS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* FWU message types that distinguish FWU services. */
+#define TFM_FWU_START                1001
+#define TFM_FWU_WRITE                1002
+#define TFM_FWU_FINISH               1003
+#define TFM_FWU_CANCEL               1004
+#define TFM_FWU_INSTALL              1005
+#define TFM_FWU_CLEAN                1006
+#define TFM_FWU_REJECT               1007
+#define TFM_FWU_REQUEST_REBOOT       1008
+#define TFM_FWU_ACCEPT               1009
+#define TFM_FWU_QUERY                1010
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* TFM_FWU_BOOTLOADER_DEFS_H */
diff --git a/components/service/fwu/psa_fwu_m/interface/update.h b/components/service/fwu/psa_fwu_m/interface/update.h
new file mode 100644
index 0000000..c11c07f
--- /dev/null
+++ b/components/service/fwu/psa_fwu_m/interface/update.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2021-2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/* PSA Firmware Update API v1.0 Beta */
+
+#ifndef PSA_UPDATE_H
+#define PSA_UPDATE_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include "psa/error.h"
+#include "tfm_fwu_defs.h"
+
+#ifndef TFM_FWU_MAX_DIGEST_SIZE
+#define TFM_FWU_MAX_DIGEST_SIZE              32
+#endif /* TFM_FWU_MAX_DIGEST_SIZE */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief The major version of this implementation of the Firmware Update API.
+ */
+#define PSA_FWU_API_VERSION_MAJOR 1
+
+/**
+ * @brief The minor version of this implementation of the Firmware Update API.
+ */
+#define PSA_FWU_API_VERSION_MINOR 0
+
+/**
+ * @brief A status code that indicates that the firmware of another component
+ *        requires updating.
+ */
+#define PSA_ERROR_DEPENDENCY_NEEDED ((psa_status_t)-156)
+
+/**
+ * @brief A status code that indicates that the system is limiting i/o
+ *        operations to avoid rapid flash exhaustion.
+ */
+#define PSA_ERROR_FLASH_ABUSE ((psa_status_t)-160)
+
+/**
+ * @brief A status code that indicates that the system does not have enough
+ *        power to carry out the request.
+ */
+#define PSA_ERROR_INSUFFICIENT_POWER ((psa_status_t)-161)
+
+/**
+ * @brief The action was completed successfully and requires a system reboot to
+ *        complete installation.
+ */
+#define PSA_SUCCESS_REBOOT ((psa_status_t)+1)
+
+/**
+ * @brief The action was completed successfully and requires a restart of the
+ *        component to complete installation.
+ */
+#define PSA_SUCCESS_RESTART ((psa_status_t)+2)
+
+/**
+ * @brief Firmware component type identifier.
+ */
+typedef uint8_t psa_fwu_component_t;
+
+/**
+ * @brief Version information about a firmware image.
+ */
+typedef struct psa_fwu_image_version_t {
+    /* The major version of an image. */
+    uint8_t major;
+    /* The minor version of an image. */
+    uint8_t minor;
+    /* The revision or patch version of an image. */
+    uint16_t patch;
+    /* The build number of an image. */
+    uint32_t build;
+} psa_fwu_image_version_t;
+
+/**
+ * @brief The READY state: the component is ready to start another update.
+ */
+#define PSA_FWU_READY 0u
+
+/**
+ * @brief The WRITING state: a new firmware image is being written to the
+ *        firmware store.
+ */
+#define PSA_FWU_WRITING 1u
+
+/**
+ * @brief The CANDIDATE state: a new firmware image is ready for installation.
+ */
+#define PSA_FWU_CANDIDATE 2u
+
+/**
+ * @brief The STAGED state: a new firmware image is queued for installation.
+ */
+#define PSA_FWU_STAGED 3u
+
+/**
+ * @brief The FAILED state: a firmware update has been cancelled or has failed.
+ */
+#define PSA_FWU_FAILED 4u
+
+/**
+ * @brief The TRIAL state: a new firmware image requires testing prior to
+ *        acceptance of the update.
+ */
+#define PSA_FWU_TRIAL 5u
+
+/**
+ * @brief The REJECTED state: a new firmware image has been rejected after
+ *        testing.
+ */
+#define PSA_FWU_REJECTED 6u
+
+/**
+ * @brief The UPDATED state: a firmware update has been successful, and the new
+ *        image is now active.
+ */
+#define PSA_FWU_UPDATED 7u
+
+/**
+ * @brief Flag to indicate whether the image data in the component staging area
+ *        is discarded at system reset.
+ */
+#define PSA_FWU_FLAG_VOLATILE_STAGING 0x00000001u
+
+/**
+ * @brief Flag to indicate whether a firmware component expects encrypted images
+ *        during an update.
+ */
+#define PSA_FWU_FLAG_ENCRYPTION 0x00000002u
+
+/**
+ * @brief The implementation-specific data in the component information
+ *        structure.
+ */
+typedef struct {
+    /* The digest of second image when store state is CANDIDATE. */
+    uint8_t candidate_digest[TFM_FWU_MAX_DIGEST_SIZE];
+ } psa_fwu_impl_info_t;
+
+/**
+ * @brief Information about the firmware store for a firmware component.
+ */
+typedef struct psa_fwu_component_info_t {
+    /* State of the component. */
+    uint8_t state;
+    /* Error for second image when store state is REJECTED or FAILED. */
+    psa_status_t error;
+    /* Version of active image. */
+    psa_fwu_image_version_t version;
+    /* Maximum image size in bytes. */
+    uint32_t max_size;
+    /* Flags that describe extra information about the firmware component. */
+    uint32_t flags;
+    /* Implementation-defined image location. */
+    uint32_t location;
+    /* Reserved for implementation-specific usage. */
+    psa_fwu_impl_info_t impl;
+} psa_fwu_component_info_t;
+
+/**
+ * @brief Retrieve the firmware store information for a specific firmware
+ *        component.
+ *
+ * @param component Firmware component for which information is requested.
+ * @param info      Output parameter for component information.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_query(psa_fwu_component_t component,
+                           psa_fwu_component_info_t *info);
+
+/**
+ * @brief Begin a firmware update operation for a specific firmware component.
+ *
+ * @param component     Identifier of the firmware component to be updated.
+ * @param manifest      A pointer to a buffer containing a detached manifest for
+ *                      the update.
+ * @param manifest_size The size of the detached manifest.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_start(psa_fwu_component_t component,
+                           const void *manifest,
+                           size_t manifest_size);
+
+/**
+ * @brief The maximum permitted size for block in psa_fwu_write(), in bytes.
+ */
+#define PSA_FWU_MAX_WRITE_SIZE TFM_CONFIG_FWU_MAX_WRITE_SIZE
+
+/**
+ * @brief Write a firmware image, or part of a firmware image, to its staging
+ *        area.
+ *
+ * @param component    Identifier of the firmware component being updated.
+ * @param image_offset The offset of the data block in the whole image.
+ * @param block        A buffer containing a block of image data.
+ * @param block_size   Size of block, in bytes.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_write(psa_fwu_component_t component,
+                           size_t image_offset,
+                           const void *block,
+                           size_t block_size);
+
+/**
+ * @brief Mark a firmware image in the staging area as ready for installation.
+ *
+ * @param component Identifier of the firmware component to install.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_finish(psa_fwu_component_t component);
+
+/**
+ * @brief Abandon an update that is in WRITING or CANDIDATE state.
+ *
+ * @param component Identifier of the firmware component to be cancelled.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_cancel(psa_fwu_component_t component);
+
+/**
+ * @brief Prepare the component for another update.
+ *
+ * @param component Identifier of the firmware component to tidy up.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_clean(psa_fwu_component_t component);
+
+/**
+ * @brief Start the installation of all firmware images that have been prepared
+ *        for update.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_install(void);
+
+/**
+ * @brief Requests the platform to reboot.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_request_reboot(void);
+
+/**
+ * @brief Abandon an installation that is in STAGED or TRIAL state.
+ *
+ * @param error An application-specific error code chosen by the application.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_reject(psa_status_t error);
+
+/**
+ * @brief Accept a firmware update that is currently in TRIAL state.
+ *
+ * @return Result status.
+ */
+psa_status_t psa_fwu_accept(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PSA_UPDATE_H */
diff --git a/components/service/fwu/test/fwu_client/direct/direct_fwu_client.cpp b/components/service/fwu/test/fwu_client/direct/direct_fwu_client.cpp
index 6afd0f2..aa4cd3e 100644
--- a/components/service/fwu/test/fwu_client/direct/direct_fwu_client.cpp
+++ b/components/service/fwu/test/fwu_client/direct/direct_fwu_client.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -8,9 +8,10 @@
 
 #include <cstring>
 
-#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
+#include "protocols/service/fwu/fwu_proto.h"
 
-direct_fwu_client::direct_fwu_client(struct update_agent *update_agent)
+direct_fwu_client::direct_fwu_client(struct update_agent **update_agent)
 	: fwu_client()
 	, m_update_agent(update_agent)
 	, m_read_buf()
@@ -25,50 +26,98 @@
 {
 }
 
-int direct_fwu_client::begin_staging(void)
+int direct_fwu_client::discover(int16_t *service_status, uint8_t *version_major,
+				uint8_t *version_minor, uint16_t *num_func,
+				uint64_t *max_payload_size, uint32_t *flags,
+				uint32_t *vendor_specific_flags, uint8_t *function_presence)
 {
-	return update_agent_begin_staging(m_update_agent);
+	struct fwu_discovery_result discovery_result = { 0 };
+	int res = 0;
+
+	res = update_agent_discover(*m_update_agent, &discovery_result);
+	if (res)
+		return res;
+
+	*service_status = discovery_result.service_status;
+	*version_major = discovery_result.version_major;
+	*version_minor = discovery_result.version_minor;
+	*max_payload_size = discovery_result.max_payload_size;
+	*flags = discovery_result.flags;
+	*vendor_specific_flags = discovery_result.vendor_specific_flags;
+
+	*num_func = 0;
+
+#define ADD_FUNC_IF_PRESENT(func, id) \
+do { \
+	if ((*m_update_agent)->interface->func != NULL) \
+		function_presence[(*num_func)++] = (id); \
+} while (0)
+
+	ADD_FUNC_IF_PRESENT(discover, FWU_FUNC_ID_DISCOVER);
+	ADD_FUNC_IF_PRESENT(begin_staging, FWU_FUNC_ID_BEGIN_STAGING);
+	ADD_FUNC_IF_PRESENT(end_staging, FWU_FUNC_ID_END_STAGING);
+	ADD_FUNC_IF_PRESENT(cancel_staging, FWU_FUNC_ID_CANCEL_STAGING);
+	ADD_FUNC_IF_PRESENT(open, FWU_FUNC_ID_OPEN);
+	ADD_FUNC_IF_PRESENT(write_stream, FWU_FUNC_ID_WRITE_STREAM);
+	ADD_FUNC_IF_PRESENT(read_stream, FWU_FUNC_ID_READ_STREAM);
+	ADD_FUNC_IF_PRESENT(commit, FWU_FUNC_ID_COMMIT);
+	ADD_FUNC_IF_PRESENT(accept_image, FWU_FUNC_ID_ACCEPT_IMAGE);
+	ADD_FUNC_IF_PRESENT(select_previous, FWU_FUNC_ID_SELECT_PREVIOUS);
+
+#undef ADD_FUNC_IF_PRESENT
+
+	return res;
+}
+
+int direct_fwu_client::begin_staging(uint32_t vendor_flags, uint32_t partial_update_count,
+				     struct uuid_octets update_guid[])
+{
+	return update_agent_begin_staging(*m_update_agent, vendor_flags, partial_update_count,
+					  update_guid);
 }
 
 int direct_fwu_client::end_staging(void)
 {
-	return update_agent_end_staging(m_update_agent);
+	return update_agent_end_staging(*m_update_agent);
 }
 
 int direct_fwu_client::cancel_staging(void)
 {
-	return update_agent_cancel_staging(m_update_agent);
+	return update_agent_cancel_staging(*m_update_agent);
 }
 
 int direct_fwu_client::accept(const struct uuid_octets *image_type_uuid)
 {
-	return update_agent_accept(m_update_agent, image_type_uuid);
+	return update_agent_accept_image(*m_update_agent, image_type_uuid);
 }
 
 int direct_fwu_client::select_previous(void)
 {
-	return update_agent_select_previous(m_update_agent);
+	return update_agent_select_previous(*m_update_agent);
 }
 
-int direct_fwu_client::open(const struct uuid_octets *uuid, uint32_t *handle)
+int direct_fwu_client::open(const struct uuid_octets *uuid, op_type op_type, uint32_t *handle)
 {
-	return update_agent_open(m_update_agent, uuid, handle);
+	return update_agent_open(*m_update_agent, uuid, (uint8_t)op_type, handle);
 }
 
 int direct_fwu_client::commit(uint32_t handle, bool accepted)
 {
-	return update_agent_commit(m_update_agent, handle, accepted);
+	uint32_t progress = 0;
+	uint32_t total_work = 0;
+
+	return update_agent_commit(*m_update_agent, handle, accepted, 0, &progress, &total_work);
 }
 
 int direct_fwu_client::write_stream(uint32_t handle, const uint8_t *data, size_t data_len)
 {
-	return update_agent_write_stream(m_update_agent, handle, data, data_len);
+	return update_agent_write_stream(*m_update_agent, handle, data, data_len);
 }
 
 int direct_fwu_client::read_stream(uint32_t handle, uint8_t *buf, size_t buf_size, size_t *read_len,
 				   size_t *total_len)
 {
-	int status = update_agent_read_stream(m_update_agent, handle, m_read_buf, READ_BUF_SIZE,
+	int status = update_agent_read_stream(*m_update_agent, handle, m_read_buf, READ_BUF_SIZE,
 					      read_len, total_len);
 
 	if (!status && buf && buf_size) {
diff --git a/components/service/fwu/test/fwu_client/direct/direct_fwu_client.h b/components/service/fwu/test/fwu_client/direct/direct_fwu_client.h
index bfa925b..744c824 100644
--- a/components/service/fwu/test/fwu_client/direct/direct_fwu_client.h
+++ b/components/service/fwu/test/fwu_client/direct/direct_fwu_client.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,10 +19,15 @@
  */
 class direct_fwu_client : public fwu_client {
 public:
-	explicit direct_fwu_client(struct update_agent *update_agent);
+	explicit direct_fwu_client(struct update_agent **update_agent);
 	~direct_fwu_client();
 
-	int begin_staging(void);
+	int discover(int16_t *service_status, uint8_t *version_major, uint8_t *version_minor,
+		     uint16_t *num_func, uint64_t *max_payload_size, uint32_t *flags,
+		     uint32_t *vendor_specific_flags, uint8_t *function_presence);
+
+	int begin_staging(uint32_t vendor_flags, uint32_t partial_update_count,
+			  struct uuid_octets update_guid[]);
 
 	int end_staging(void);
 
@@ -32,7 +37,7 @@
 
 	int select_previous(void);
 
-	int open(const struct uuid_octets *uuid, uint32_t *handle);
+	int open(const struct uuid_octets *uuid, op_type op_type, uint32_t *handle);
 
 	int commit(uint32_t handle, bool accepted);
 
@@ -44,7 +49,7 @@
 private:
 	static const size_t READ_BUF_SIZE = 512;
 
-	struct update_agent *m_update_agent;
+	struct update_agent **m_update_agent;
 	uint8_t m_read_buf[READ_BUF_SIZE];
 };
 
diff --git a/components/service/fwu/test/fwu_client/fwu_client.h b/components/service/fwu/test/fwu_client/fwu_client.h
index 55f4c87..072d647 100644
--- a/components/service/fwu/test/fwu_client/fwu_client.h
+++ b/components/service/fwu/test/fwu_client/fwu_client.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -19,6 +19,11 @@
  */
 class fwu_client {
 public:
+	enum class op_type {
+		READ = 0,
+		WRITE = 1,
+	};
+
 	fwu_client()
 	{
 	}
@@ -27,7 +32,13 @@
 	{
 	}
 
-	virtual int begin_staging(void) = 0;
+	virtual int discover(int16_t *service_status, uint8_t *version_major,
+			     uint8_t *version_minor, uint16_t *num_func, uint64_t *max_payload_size,
+			     uint32_t *flags, uint32_t *vendor_specific_flags,
+			     uint8_t *function_presence) = 0;
+
+	virtual int begin_staging(uint32_t vendor_flags, uint32_t partial_update_count,
+				  struct uuid_octets update_guid[]) = 0;
 
 	virtual int end_staging(void) = 0;
 
@@ -37,7 +48,7 @@
 
 	virtual int select_previous(void) = 0;
 
-	virtual int open(const struct uuid_octets *uuid, uint32_t *handle) = 0;
+	virtual int open(const struct uuid_octets *uuid, op_type op_type, uint32_t *handle) = 0;
 
 	virtual int commit(uint32_t handle, bool accepted) = 0;
 
diff --git a/components/service/fwu/test/fwu_client/remote/remote_fwu_client.cpp b/components/service/fwu/test/fwu_client/remote/remote_fwu_client.cpp
index 803dfe6..16dffc4 100644
--- a/components/service/fwu/test/fwu_client/remote/remote_fwu_client.cpp
+++ b/components/service/fwu/test/fwu_client/remote/remote_fwu_client.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,9 +12,10 @@
 
 #include "protocols/rpc/common/packed-c/encoding.h"
 #include "protocols/rpc/common/packed-c/status.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
-#include "protocols/service/fwu/packed-c/opcodes.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "protocols/service/fwu/opcodes.h"
+#include "protocols/service/fwu/status.h"
+#include "util.h"
 
 remote_fwu_client::remote_fwu_client()
 	: fwu_client()
@@ -68,6 +69,58 @@
 	}
 }
 
+rpc_call_handle remote_fwu_client::fwu_caller_session_begin(struct rpc_caller_session *session,
+					uint8_t **request_buffer, size_t request_length,
+					size_t response_max_length)
+{
+	struct fwu_request_header *req_header = NULL;
+	rpc_call_handle handle = NULL;
+
+	request_length += sizeof(*req_header);
+	response_max_length += sizeof(struct fwu_response_header);
+
+	handle = rpc_caller_session_begin(session, (uint8_t **)&req_header, request_length,
+					  response_max_length);
+	if (!handle)
+		return handle;
+
+	*request_buffer = req_header->payload;
+
+	return new fwu_call_handle{req_header, handle};
+}
+
+rpc_status_t remote_fwu_client::fwu_caller_session_invoke(rpc_call_handle handle, uint32_t opcode,
+				uint8_t **response_buffer, size_t *response_length,
+				service_status_t *service_status)
+{
+	struct fwu_response_header *resp_header = NULL;
+	fwu_call_handle *fwu_handle = (fwu_call_handle *)handle;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	fwu_handle->req_header->func_id = opcode;
+
+	status = rpc_caller_session_invoke(fwu_handle->handle, 0, (uint8_t **)&resp_header,
+					   response_length, service_status);
+	if (status != RPC_SUCCESS)
+		return status;
+
+	*service_status = resp_header->status;
+	*response_buffer = resp_header->payload;
+
+	return status;
+}
+
+rpc_status_t remote_fwu_client::fwu_caller_session_end(rpc_call_handle handle)
+{
+	fwu_call_handle *fwu_handle = (fwu_call_handle *)handle;
+	rpc_status_t status = RPC_ERROR_INTERNAL;
+
+	status = rpc_caller_session_end(fwu_handle->handle);
+	delete fwu_handle;
+
+	return status;
+}
+
 int remote_fwu_client::invoke_no_param(unsigned int opcode)
 {
 	int fwu_status = FWU_STATUS_NOT_AVAILABLE;
@@ -78,45 +131,140 @@
 	if (!m_service_context)
 		return fwu_status;
 
-	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
+	call_handle = fwu_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 		uint8_t *resp_buf;
 		size_t resp_len;
 		service_status_t service_status;
 
-		m_client.rpc_status = rpc_caller_session_invoke(call_handle, opcode,
+		m_client.rpc_status = fwu_caller_session_invoke(call_handle, opcode,
 							&resp_buf, &resp_len, &service_status);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED)
 			fwu_status = service_status;
 
-		rpc_caller_session_end(call_handle);
+		fwu_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
 }
 
-int remote_fwu_client::begin_staging(void)
+int remote_fwu_client::discover(int16_t *service_status, uint8_t *version_major,
+				uint8_t *version_minor, uint16_t *num_func,
+				uint64_t *max_payload_size, uint32_t *flags,
+				uint32_t *vendor_specific_flags, uint8_t *function_presence)
 {
-	return invoke_no_param(TS_FWU_OPCODE_BEGIN_STAGING);
+	int fwu_status = FWU_STATUS_NOT_AVAILABLE;
+	struct fwu_discover_out *resp_msg = NULL;
+	size_t max_resp_len = 0;
+
+	if (!m_service_context)
+		return fwu_status;
+
+	if (ADD_OVERFLOW(FWU_FUNC_ID_COUNT, sizeof(*resp_msg), &max_resp_len))
+		return FWU_STATUS_OUT_OF_BOUNDS;
+
+	rpc_call_handle call_handle = NULL;
+	uint8_t *req_buf = NULL;
+
+	call_handle = fwu_caller_session_begin(m_rpc_session, &req_buf, 0, max_resp_len);
+
+	if (call_handle) {
+		uint8_t *resp_buf = NULL;
+		size_t resp_len = 0;
+		service_status_t req_service_status = 0;
+
+		m_client.rpc_status = fwu_caller_session_invoke(call_handle, FWU_FUNC_ID_DISCOVER,
+								&resp_buf, &resp_len,
+								&req_service_status);
+
+		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
+			fwu_status = req_service_status;
+
+			if (fwu_status == FWU_STATUS_SUCCESS) {
+				if (resp_len <= max_resp_len) {
+					resp_msg = (struct fwu_discover_out *)resp_buf;
+
+					*service_status = resp_msg->service_status;
+					*version_major = resp_msg->version_major;
+					*num_func = resp_msg->num_func;
+					*max_payload_size = resp_msg->max_payload_size;
+					*flags = resp_msg->flags;
+					*vendor_specific_flags = resp_msg->vendor_specific_flags;
+					memcpy(function_presence, resp_msg->function_presence,
+					resp_msg->num_func);
+				} else {
+					fwu_status = FWU_STATUS_OUT_OF_BOUNDS;
+				}
+			}
+		}
+
+		fwu_caller_session_end(call_handle);
+	}
+
+	return fwu_status;
+}
+
+int remote_fwu_client::begin_staging(uint32_t vendor_flags, uint32_t partial_update_count,
+				     struct uuid_octets update_guid[])
+{
+	int fwu_status = FWU_STATUS_NOT_AVAILABLE;
+	struct fwu_begin_staging_in *req_msg = NULL;
+	size_t req_len = 0;
+	size_t uuids_size = 0;
+
+	if (!m_service_context)
+		return fwu_status;
+
+	if (MUL_OVERFLOW(partial_update_count, sizeof(*update_guid), &uuids_size) ||
+	    ADD_OVERFLOW(uuids_size, sizeof(*req_msg), &req_len))
+		return fwu_status;
+
+	rpc_call_handle call_handle = NULL;
+	uint8_t *req_buf = NULL;
+
+	call_handle = fwu_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
+
+	if (call_handle) {
+		uint8_t *resp_buf = NULL;
+		size_t resp_len = 0;
+		service_status_t service_status = 0;
+
+		req_msg = (struct fwu_begin_staging_in *)req_buf;
+		req_msg->reserved = 0;
+		req_msg->vendor_flags = vendor_flags;
+		req_msg->partial_update_count = partial_update_count;
+		memcpy(req_msg->update_guid, update_guid, uuids_size);
+
+		m_client.rpc_status = fwu_caller_session_invoke(call_handle,
+							FWU_FUNC_ID_BEGIN_STAGING,
+							&resp_buf, &resp_len, &service_status);
+
+		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED)
+			fwu_status = service_status;
+
+		fwu_caller_session_end(call_handle);
+	}
+
+	return fwu_status;
 }
 
 int remote_fwu_client::end_staging(void)
 {
-	return invoke_no_param(TS_FWU_OPCODE_END_STAGING);
+	return invoke_no_param(FWU_FUNC_ID_END_STAGING);
 }
 
 int remote_fwu_client::cancel_staging(void)
 {
-	return invoke_no_param(TS_FWU_OPCODE_CANCEL_STAGING);
+	return invoke_no_param(FWU_FUNC_ID_CANCEL_STAGING);
 }
 
 int remote_fwu_client::accept(const struct uuid_octets *image_type_uuid)
 {
 	int fwu_status = FWU_STATUS_NOT_AVAILABLE;
-	struct ts_fwu_accept_image_in req_msg = { 0 };
-	size_t req_len = sizeof(struct ts_fwu_accept_image_in);
+	struct fwu_accept_image_in req_msg = { 0 };
+	size_t req_len = sizeof(struct fwu_accept_image_in);
 
 	if (!m_service_context)
 		return fwu_status;
@@ -126,7 +274,7 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
+	call_handle = fwu_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 		uint8_t *resp_buf;
@@ -135,14 +283,14 @@
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		m_client.rpc_status = rpc_caller_session_invoke(call_handle,
-							TS_FWU_OPCODE_ACCEPT_IMAGE,
+		m_client.rpc_status = fwu_caller_session_invoke(call_handle,
+							FWU_FUNC_ID_ACCEPT_IMAGE,
 							&resp_buf, &resp_len, &service_status);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED)
 			fwu_status = service_status;
 
-		rpc_caller_session_end(call_handle);
+		fwu_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
@@ -150,25 +298,26 @@
 
 int remote_fwu_client::select_previous(void)
 {
-	return invoke_no_param(TS_FWU_OPCODE_SELECT_PREVIOUS);
+	return invoke_no_param(FWU_FUNC_ID_SELECT_PREVIOUS);
 }
 
-int remote_fwu_client::open(const struct uuid_octets *uuid, uint32_t *handle)
+int remote_fwu_client::open(const struct uuid_octets *uuid, op_type op_type, uint32_t *handle)
 {
 	int fwu_status = FWU_STATUS_NOT_AVAILABLE;
-	struct ts_fwu_open_in req_msg = { 0 };
-	size_t req_len = sizeof(struct ts_fwu_open_in);
+	struct fwu_open_in req_msg = { 0 };
+	size_t req_len = sizeof(struct fwu_open_in);
 
 	if (!m_service_context)
 		return fwu_status;
 
 	memcpy(req_msg.image_type_uuid, uuid->octets, OSF_UUID_OCTET_LEN);
+	req_msg.op_type = static_cast<uint8_t>(op_type);
 
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len,
-					       sizeof(struct ts_fwu_open_out));
+	call_handle = fwu_caller_session_begin(m_rpc_session, &req_buf, req_len,
+					       sizeof(struct fwu_open_out));
 
 	if (call_handle) {
 		uint8_t *resp_buf;
@@ -177,23 +326,23 @@
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		m_client.rpc_status = rpc_caller_session_invoke(call_handle,
-							TS_FWU_OPCODE_OPEN, &resp_buf,
+		m_client.rpc_status = fwu_caller_session_invoke(call_handle,
+							FWU_FUNC_ID_OPEN, &resp_buf,
 							&resp_len, &service_status);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
 			fwu_status = service_status;
 
 			if ((fwu_status == FWU_STATUS_SUCCESS) &&
-			    (resp_len >= sizeof(struct ts_fwu_open_out))) {
-				struct ts_fwu_open_out resp_msg;
+			    (resp_len >= sizeof(struct fwu_open_out))) {
+				struct fwu_open_out resp_msg;
 
-				memcpy(&resp_msg, resp_buf, sizeof(struct ts_fwu_open_out));
+				memcpy(&resp_msg, resp_buf, sizeof(struct fwu_open_out));
 				*handle = resp_msg.handle;
 			}
 		}
 
-		rpc_caller_session_end(call_handle);
+		fwu_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
@@ -202,8 +351,8 @@
 int remote_fwu_client::commit(uint32_t handle, bool accepted)
 {
 	int fwu_status = FWU_STATUS_NOT_AVAILABLE;
-	struct ts_fwu_commit_in req_msg = { 0 };
-	size_t req_len = sizeof(struct ts_fwu_commit_in);
+	struct fwu_commit_in req_msg = { 0 };
+	size_t req_len = sizeof(struct fwu_commit_in);
 
 	if (!m_service_context)
 		return fwu_status;
@@ -214,7 +363,7 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
+	call_handle = fwu_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
 
 	if (call_handle) {
 		uint8_t *resp_buf;
@@ -223,14 +372,14 @@
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		m_client.rpc_status = rpc_caller_session_invoke(call_handle,
-							TS_FWU_OPCODE_COMMIT, &resp_buf,
+		m_client.rpc_status = fwu_caller_session_invoke(call_handle,
+							FWU_FUNC_ID_COMMIT, &resp_buf,
 							&resp_len, &service_status);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED)
 			fwu_status = service_status;
 
-		rpc_caller_session_end(call_handle);
+		fwu_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
@@ -238,7 +387,7 @@
 
 int remote_fwu_client::write_stream(uint32_t handle, const uint8_t *data, size_t data_len)
 {
-	size_t proto_overhead = offsetof(ts_fwu_write_stream_in, payload);
+	size_t proto_overhead = offsetof(fwu_write_stream_in, payload);
 	size_t max_payload = (m_client.service_info.max_payload > proto_overhead) ?
 				     m_client.service_info.max_payload - proto_overhead :
 				     0;
@@ -253,7 +402,7 @@
 		return FWU_STATUS_NOT_AVAILABLE;
 
 	size_t total_written = 0;
-	struct ts_fwu_write_stream_in req_msg;
+	struct fwu_write_stream_in req_msg;
 
 	req_msg.handle = handle;
 
@@ -267,7 +416,7 @@
 		rpc_call_handle call_handle;
 		uint8_t *req_buf;
 
-		call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
+		call_handle = fwu_caller_session_begin(m_rpc_session, &req_buf, req_len, 0);
 
 		if (call_handle) {
 			uint8_t *resp_buf;
@@ -279,11 +428,11 @@
 
 			total_written += write_len;
 
-			m_client.rpc_status = rpc_caller_session_invoke(call_handle,
-								TS_FWU_OPCODE_WRITE_STREAM,
+			m_client.rpc_status = fwu_caller_session_invoke(call_handle,
+								FWU_FUNC_ID_WRITE_STREAM,
 								&resp_buf, &resp_len, &service_status);
 
-			rpc_caller_session_end(call_handle);
+			fwu_caller_session_end(call_handle);
 
 			if (m_client.rpc_status != TS_RPC_CALL_ACCEPTED)
 				return FWU_STATUS_NOT_AVAILABLE;
@@ -302,8 +451,8 @@
 				   size_t *total_len)
 {
 	int fwu_status = FWU_STATUS_NOT_AVAILABLE;
-	struct ts_fwu_read_stream_in req_msg;
-	size_t req_len = sizeof(struct ts_fwu_read_stream_in);
+	struct fwu_read_stream_in req_msg;
+	size_t req_len = sizeof(struct fwu_read_stream_in);
 
 	if (!m_service_context)
 		return fwu_status;
@@ -316,8 +465,8 @@
 	rpc_call_handle call_handle;
 	uint8_t *req_buf;
 
-	call_handle = rpc_caller_session_begin(m_rpc_session, &req_buf, req_len,
-					       sizeof(struct ts_fwu_read_stream_out) + buf_size);
+	call_handle = fwu_caller_session_begin(m_rpc_session, &req_buf, req_len,
+					       sizeof(struct fwu_read_stream_out) + buf_size);
 
 	if (call_handle) {
 		uint8_t *resp_buf;
@@ -326,18 +475,18 @@
 
 		memcpy(req_buf, &req_msg, req_len);
 
-		m_client.rpc_status = rpc_caller_session_invoke(call_handle,
-							TS_FWU_OPCODE_READ_STREAM,
+		m_client.rpc_status = fwu_caller_session_invoke(call_handle,
+							FWU_FUNC_ID_READ_STREAM,
 							&resp_buf, &resp_len, &service_status);
 
-		size_t proto_overhead = offsetof(ts_fwu_read_stream_out, payload);
+		size_t proto_overhead = offsetof(fwu_read_stream_out, payload);
 
 		if (m_client.rpc_status == TS_RPC_CALL_ACCEPTED) {
 			fwu_status = service_status;
 
 			if ((fwu_status == FWU_STATUS_SUCCESS) && (resp_len >= proto_overhead)) {
-				const struct ts_fwu_read_stream_out *resp_msg =
-					(const struct ts_fwu_read_stream_out *)resp_buf;
+				const struct fwu_read_stream_out *resp_msg =
+					(const struct fwu_read_stream_out *)resp_buf;
 
 				*read_len = resp_msg->read_bytes;
 				*total_len = resp_msg->total_bytes;
@@ -352,7 +501,7 @@
 			}
 		}
 
-		rpc_caller_session_end(call_handle);
+		fwu_caller_session_end(call_handle);
 	}
 
 	return fwu_status;
diff --git a/components/service/fwu/test/fwu_client/remote/remote_fwu_client.h b/components/service/fwu/test/fwu_client/remote/remote_fwu_client.h
index ce0511c..c5a1167 100644
--- a/components/service/fwu/test/fwu_client/remote/remote_fwu_client.h
+++ b/components/service/fwu/test/fwu_client/remote/remote_fwu_client.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,7 +21,12 @@
 	remote_fwu_client();
 	~remote_fwu_client();
 
-	int begin_staging(void);
+	int discover(int16_t *service_status, uint8_t *version_major, uint8_t *version_minor,
+		     uint16_t *num_func, uint64_t *max_payload_size, uint32_t *flags,
+		     uint32_t *vendor_specific_flags, uint8_t *function_presence);
+
+	int begin_staging(uint32_t vendor_flags, uint32_t partial_update_count,
+			  struct uuid_octets update_guid[]);
 
 	int end_staging(void);
 
@@ -31,7 +36,7 @@
 
 	int select_previous(void);
 
-	int open(const struct uuid_octets *uuid, uint32_t *handle);
+	int open(const struct uuid_octets *uuid, op_type op_type, uint32_t *handle);
 
 	int commit(uint32_t handle, bool accepted);
 
@@ -45,6 +50,22 @@
 	void open_session(void);
 	void close_session(void);
 
+	struct fwu_call_handle {
+		struct fwu_request_header *req_header;
+		rpc_call_handle handle;
+	};
+
+	rpc_call_handle fwu_caller_session_begin(struct rpc_caller_session *session,
+					 uint8_t **request_buffer, size_t request_length,
+					 size_t response_max_length);
+
+
+	rpc_status_t fwu_caller_session_invoke(rpc_call_handle handle, uint32_t opcode,
+				       uint8_t **response_buffer, size_t *response_length,
+				       service_status_t *service_status);
+
+	rpc_status_t fwu_caller_session_end(rpc_call_handle handle);
+
 	struct service_client m_client;
 	struct rpc_caller_session *m_rpc_session;
 	struct service_context *m_service_context;
diff --git a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
index 5415cc7..79f0766 100644
--- a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
+++ b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,12 +14,13 @@
 #include "common/endian/le.h"
 #include "media/disk/guid.h"
 #include "media/volume/index/volume_index.h"
+#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
 #include "service/fwu/fw_store/banked/metadata_serializer/v1/metadata_serializer_v1.h"
 #include "service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h"
 #include "service/fwu/fw_store/banked/volume_id.h"
 #include "service/fwu/inspector/direct/direct_fw_inspector.h"
 #include "service/fwu/installer/installer_index.h"
-#include "service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.h"
 #include "service/fwu/test/fwu_client/direct/direct_fwu_client.h"
 #include "service/fwu/test/metadata_fetcher/volume/volume_metadata_fetcher.h"
 
@@ -54,19 +55,7 @@
 
 	install_factory_images(num_locations);
 
-	/* Initialise fwu service provider prior to boot to ensure that a
-	 * viable service interface exists to safely handle an incoming
-	 * request that occurs prior to the boot method being called.
-	 * Note that the update_agent is in the de-initialized state so
-	 * any operations will be denied.
-	 */
-	memset(&m_update_agent, 0, sizeof(m_update_agent));
-	m_update_agent.state = FWU_STATE_DEINITIALZED;
-
-	m_service_iface = fwu_provider_init(&m_fwu_provider, &m_update_agent);
-
-	fwu_provider_register_serializer(&m_fwu_provider, TS_RPC_ENCODING_PACKED_C,
-					 packedc_fwu_provider_serializer_instance());
+	m_service_iface = fwu_provider_init(&m_fwu_provider, NULL);
 
 	m_metadata_checker = create_metadata_checker();
 }
@@ -119,9 +108,11 @@
 	int status = banked_fw_store_init(&m_fw_store, select_metadata_serializer());
 	LONGS_EQUAL(0, status);
 
-	status = update_agent_init(&m_update_agent, m_boot_info.boot_index,
-				   direct_fw_inspector_inspect, &m_fw_store);
-	LONGS_EQUAL(0, status);
+	m_update_agent = update_agent_init(m_boot_info.boot_index, direct_fw_inspector_inspect,
+					   &m_fw_store);
+	CHECK(m_update_agent != NULL);
+
+	m_fwu_provider.update_agent = m_update_agent;
 
 	m_is_booted = true;
 }
@@ -132,9 +123,10 @@
 		return;
 
 	/* Ensure all install streams are closed */
-	update_agent_cancel_staging(&m_update_agent);
+	update_agent_cancel_staging(m_update_agent);
 
-	update_agent_deinit(&m_update_agent);
+	m_fwu_provider.update_agent = NULL;
+	update_agent_deinit(m_update_agent);
 	banked_fw_store_deinit(&m_fw_store);
 
 	m_is_booted = false;
diff --git a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
index f10d2c5..8a2bde3 100644
--- a/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
+++ b/components/service/fwu/test/fwu_dut/sim/sim_fwu_dut.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,13 +15,14 @@
 #include "service/block_storage/block_store/device/ram/ram_block_store.h"
 #include "service/block_storage/block_store/partitioned/partitioned_block_store.h"
 #include "service/fwu/agent/fw_directory.h"
-#include "service/fwu/agent/update_agent.h"
+#include "service/fwu/common/update_agent_interface.h"
 #include "service/fwu/fw_store/banked/bank_scheme.h"
 #include "service/fwu/fw_store/banked/banked_fw_store.h"
 #include "service/fwu/installer/copy/copy_installer.h"
 #include "service/fwu/installer/raw/raw_installer.h"
 #include "service/fwu/provider/fwu_provider.h"
 #include "service/fwu/test/fwu_client/fwu_client.h"
+#include "service/fwu/test/fwu_client/direct/direct_fwu_client.h"
 #include "service/fwu/test/fwu_dut/fwu_dut.h"
 #include "service/fwu/test/metadata_checker/metadata_checker.h"
 
@@ -119,7 +120,7 @@
 	struct copy_installer m_copy_installer_pool[MAX_LOCATIONS];
 
 	/* The core fwu service components */
-	struct update_agent m_update_agent;
+	struct update_agent *m_update_agent;
 	struct fw_store m_fw_store;
 	struct fwu_provider m_fwu_provider;
 };
diff --git a/components/service/fwu/test/image_directory_checker/image_directory_checker.cpp b/components/service/fwu/test/image_directory_checker/image_directory_checker.cpp
index 49610c1..85eee97 100644
--- a/components/service/fwu/test/image_directory_checker/image_directory_checker.cpp
+++ b/components/service/fwu/test/image_directory_checker/image_directory_checker.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -34,7 +34,7 @@
 
 	uuid_guid_octets_from_canonical(&uuid, FWU_DIRECTORY_CANONICAL_UUID);
 
-	status = fwu_client->open(&uuid, &stream_handle);
+	status = fwu_client->open(&uuid, fwu_client::op_type::READ, &stream_handle);
 	if (status)
 		return status;
 
@@ -69,9 +69,9 @@
 {
 	size_t num_images = 0;
 
-	if (m_total_read_len >= offsetof(struct ts_fwu_image_directory, img_info_entry)) {
-		const struct ts_fwu_image_directory *header =
-			(const struct ts_fwu_image_directory *)m_buf;
+	if (m_total_read_len >= offsetof(struct fwu_image_directory, img_info_entry)) {
+		const struct fwu_image_directory *header =
+			(const struct fwu_image_directory *)m_buf;
 
 		num_images = header->num_images;
 	}
@@ -86,22 +86,22 @@
 	       (memcmp(this->m_buf, rhs.m_buf, this->m_total_read_len) == 0);
 }
 
-const struct ts_fwu_image_directory *image_directory_checker::get_header(void) const
+const struct fwu_image_directory *image_directory_checker::get_header(void) const
 {
-	const struct ts_fwu_image_directory *header = NULL;
+	const struct fwu_image_directory *header = NULL;
 
-	if (m_total_read_len >= offsetof(struct ts_fwu_image_directory, img_info_entry))
-		header = (const struct ts_fwu_image_directory *)m_buf;
+	if (m_total_read_len >= offsetof(struct fwu_image_directory, img_info_entry))
+		header = (const struct fwu_image_directory *)m_buf;
 
 	return header;
 }
 
-const struct ts_fwu_image_info_entry *
+const struct fwu_image_info_entry *
 image_directory_checker::find_entry(const struct uuid_octets *img_type_uuid) const
 {
-	const struct ts_fwu_image_info_entry *found_entry = NULL;
+	const struct fwu_image_info_entry *found_entry = NULL;
 
-	const struct ts_fwu_image_directory *header = get_header();
+	const struct fwu_image_directory *header = get_header();
 
 	if (header) {
 		unsigned int index = 0;
@@ -123,8 +123,8 @@
 
 void image_directory_checker::alloc_buffer(void)
 {
-	m_buf_size = offsetof(struct ts_fwu_image_directory, img_info_entry) +
-		     MAX_IMAGES * sizeof(ts_fwu_image_info_entry);
+	m_buf_size = offsetof(struct fwu_image_directory, img_info_entry) +
+		     MAX_IMAGES * sizeof(fwu_image_info_entry);
 
 	m_buf = new uint8_t[m_buf_size];
 	assert(m_buf);
diff --git a/components/service/fwu/test/image_directory_checker/image_directory_checker.h b/components/service/fwu/test/image_directory_checker/image_directory_checker.h
index a8594a3..1e0bbe2 100644
--- a/components/service/fwu/test/image_directory_checker/image_directory_checker.h
+++ b/components/service/fwu/test/image_directory_checker/image_directory_checker.h
@@ -11,7 +11,7 @@
 #include <cstdint>
 
 #include "common/uuid/uuid.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
+#include "protocols/service/fwu/fwu_proto.h"
 #include "service/fwu/test/fwu_client/fwu_client.h"
 
 /*
@@ -29,8 +29,8 @@
 
 	bool is_contents_equal(const image_directory_checker &rhs) const;
 
-	const struct ts_fwu_image_directory *get_header(void) const;
-	const struct ts_fwu_image_info_entry *
+	const struct fwu_image_directory *get_header(void) const;
+	const struct fwu_image_info_entry *
 	find_entry(const struct uuid_octets *img_type_uuid) const;
 
 private:
diff --git a/components/service/fwu/test/metadata_checker/metadata_checker_v1.cpp b/components/service/fwu/test/metadata_checker/metadata_checker_v1.cpp
index f64037c..733c756 100644
--- a/components/service/fwu/test/metadata_checker/metadata_checker_v1.cpp
+++ b/components/service/fwu/test/metadata_checker/metadata_checker_v1.cpp
@@ -8,7 +8,7 @@
 
 #include <CppUTest/TestHarness.h>
 
-#include "protocols/service/fwu/packed-c/metadata_v1.h"
+#include "protocols/service/fwu/metadata_v1.h"
 #include "service/fwu/agent/fw_directory.h"
 
 const size_t metadata_checker_v1::MAX_FWU_METADATA_SIZE =
diff --git a/components/service/fwu/test/metadata_checker/metadata_checker_v2.cpp b/components/service/fwu/test/metadata_checker/metadata_checker_v2.cpp
index e51ed32..e4a853c 100644
--- a/components/service/fwu/test/metadata_checker/metadata_checker_v2.cpp
+++ b/components/service/fwu/test/metadata_checker/metadata_checker_v2.cpp
@@ -8,7 +8,7 @@
 
 #include <CppUTest/TestHarness.h>
 
-#include "protocols/service/fwu/packed-c/metadata_v2.h"
+#include "protocols/service/fwu/metadata_v2.h"
 #include "service/fwu/agent/fw_directory.h"
 
 const size_t metadata_checker_v2::MAX_FWU_METADATA_SIZE =
diff --git a/components/service/fwu/test/metadata_fetcher/client/client_metadata_fetcher.cpp b/components/service/fwu/test/metadata_fetcher/client/client_metadata_fetcher.cpp
index 77d211c..49e1455 100644
--- a/components/service/fwu/test/metadata_fetcher/client/client_metadata_fetcher.cpp
+++ b/components/service/fwu/test/metadata_fetcher/client/client_metadata_fetcher.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +10,7 @@
 #include <cstring>
 
 #include "common/uuid/uuid.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
+#include "protocols/service/fwu/fwu_proto.h"
 
 client_metadata_fetcher::client_metadata_fetcher(fwu_client *fwu_client)
 	: metadata_fetcher()
@@ -40,7 +40,7 @@
 
 	uuid_guid_octets_from_canonical(&uuid, FWU_METADATA_CANONICAL_UUID);
 
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::READ, &stream_handle);
 	LONGS_EQUAL(0, status);
 
 	size_t read_len = 0;
diff --git a/components/service/fwu/test/ref_scenarios/image_directory_tests.cpp b/components/service/fwu/test/ref_scenarios/image_directory_tests.cpp
index 453525b..2332522 100644
--- a/components/service/fwu/test/ref_scenarios/image_directory_tests.cpp
+++ b/components/service/fwu/test/ref_scenarios/image_directory_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -91,7 +91,7 @@
 		int status = 0;
 		uint32_t stream_handle = 0;
 
-		status = m_fwu_client->open(&uuid, &stream_handle);
+		status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 		LONGS_EQUAL(0, status);
 
 		stream_handles.push_back(stream_handle);
@@ -146,13 +146,13 @@
 	status = checker.fetch_image_directory(m_fwu_client);
 	LONGS_EQUAL(0, status);
 
-	const struct ts_fwu_image_directory *dir_header = checker.get_header();
+	const struct fwu_image_directory *dir_header = checker.get_header();
 
 	/* Expect directory header to reflect correct values */
 	CHECK_TRUE(dir_header);
-	UNSIGNED_LONGS_EQUAL(offsetof(struct ts_fwu_image_directory, img_info_entry),
+	UNSIGNED_LONGS_EQUAL(offsetof(struct fwu_image_directory, img_info_entry),
 			     dir_header->img_info_offset);
-	UNSIGNED_LONGS_EQUAL(sizeof(struct ts_fwu_image_info_entry), dir_header->img_info_size);
+	UNSIGNED_LONGS_EQUAL(sizeof(struct fwu_image_info_entry), dir_header->img_info_size);
 	UNSIGNED_LONGS_EQUAL(2, dir_header->directory_version);
 	UNSIGNED_LONGS_EQUAL(1, dir_header->correct_boot);
 	UNSIGNED_LONGS_EQUAL(0, dir_header->reserved);
@@ -163,7 +163,7 @@
 
 	m_dut->whole_volume_image_type_uuid(0, &expected_img_type_uuid);
 
-	const struct ts_fwu_image_info_entry *image_entry =
+	const struct fwu_image_info_entry *image_entry =
 		checker.find_entry(&expected_img_type_uuid);
 
 	CHECK_TRUE(image_entry);
@@ -187,7 +187,7 @@
 	status = checker.fetch_image_directory(m_fwu_client);
 	LONGS_EQUAL(0, status);
 
-	const struct ts_fwu_image_directory *dir_header = checker.get_header();
+	const struct fwu_image_directory *dir_header = checker.get_header();
 
 	/* Expect directory header to reflect correct values */
 	CHECK_TRUE(dir_header);
@@ -201,7 +201,7 @@
 
 		m_dut->whole_volume_image_type_uuid(0, &expected_img_type_uuid);
 
-		const struct ts_fwu_image_info_entry *image_entry =
+		const struct fwu_image_info_entry *image_entry =
 			checker.find_entry(&expected_img_type_uuid);
 
 		CHECK_TRUE(image_entry);
@@ -226,7 +226,7 @@
 	status = checker.fetch_image_directory(m_fwu_client);
 	LONGS_EQUAL(0, status);
 
-	const struct ts_fwu_image_directory *dir_header = checker.get_header();
+	const struct fwu_image_directory *dir_header = checker.get_header();
 
 	/* Expect directory header to reflect correct values */
 	CHECK_TRUE(dir_header);
diff --git a/components/service/fwu/test/ref_scenarios/invalid_behaviour_tests.cpp b/components/service/fwu/test/ref_scenarios/invalid_behaviour_tests.cpp
index 100940a..3a67dbc 100644
--- a/components/service/fwu/test/ref_scenarios/invalid_behaviour_tests.cpp
+++ b/components/service/fwu/test/ref_scenarios/invalid_behaviour_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <CppUTest/TestHarness.h>
 #include <vector>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/test/fwu_dut/fwu_dut.h"
 #include "service/fwu/test/fwu_dut_factory/fwu_dut_factory.h"
 #include "service/fwu/test/image_directory_checker/image_directory_checker.h"
@@ -64,7 +64,7 @@
 
 	/* Open a fw image when not STAGING */
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_DENIED, status);
 
 	/* Write to a stream when not STAGING. Note also that it's not possible
@@ -103,11 +103,11 @@
 	m_dut->boot();
 
 	/* Expect to be able to transition to STAGING */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	/* And re-enter STAGING (implicit cancel) */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	/* Opening a couple of streams for installing images associated
@@ -117,11 +117,11 @@
 	uint32_t stream_handle2 = 0;
 
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle1);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle1);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	m_dut->whole_volume_image_type_uuid(1, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle2);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle2);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	/* Attempting to end staging with open install streams should fail */
@@ -184,14 +184,14 @@
 	m_dut->boot();
 
 	/* Expect to be able to transition to STAGING */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	/* Install an image into location 0 */
 	uint32_t stream_handle = 0;
 
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	std::vector<uint8_t> image_data;
@@ -214,7 +214,7 @@
 	/* If we've transitioned to TRAIL, attempting to begin staging
 	 * again should be denied.
 	 */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_DENIED, status);
 
 	/* Activate the update. We'd expect the update to have been installed
@@ -226,7 +226,7 @@
 	/* If all's well, the DUT should have rebooted to TRIAL. Confirm this by
 	 * trying to begin staging - this should be denied.
 	 */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_DENIED, status);
 
 	/* All other staging related operations should also be denied */
@@ -238,7 +238,7 @@
 
 	/* Attempting to install images should also be denied */
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_DENIED, status);
 
 	/* Reading the image directory should be ok though */
@@ -250,10 +250,10 @@
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	/* Should have transitioned back to REGULAR */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	status = m_fwu_client->cancel_staging();
diff --git a/components/service/fwu/test/ref_scenarios/oversize_image_tests.cpp b/components/service/fwu/test/ref_scenarios/oversize_image_tests.cpp
index c8d91a1..2dba6e4 100644
--- a/components/service/fwu/test/ref_scenarios/oversize_image_tests.cpp
+++ b/components/service/fwu/test/ref_scenarios/oversize_image_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <CppUTest/TestHarness.h>
 #include <vector>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/test/fwu_dut/fwu_dut.h"
 #include "service/fwu/test/fwu_dut_factory/fwu_dut_factory.h"
 #include "service/fwu/test/image_directory_checker/image_directory_checker.h"
@@ -39,7 +39,7 @@
 		int status = dir_checker.fetch_image_directory(m_fwu_client);
 		LONGS_EQUAL(0, status);
 
-		const struct ts_fwu_image_info_entry *img_entry = dir_checker.find_entry(uuid);
+		const struct fwu_image_info_entry *img_entry = dir_checker.find_entry(uuid);
 		CHECK_TRUE(img_entry);
 
 		return static_cast<size_t>(img_entry->img_max_size);
@@ -70,10 +70,10 @@
 	m_dut->generate_image_data(&image_data, img_size);
 
 	/* Install the image */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	status = m_fwu_client->write_stream(stream_handle,
@@ -114,10 +114,10 @@
 	m_dut->generate_image_data(&image_data, img_size);
 
 	/* Install the image */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	status = m_fwu_client->write_stream(stream_handle,
@@ -156,10 +156,10 @@
 	m_dut->generate_image_data(&image_data, img_size);
 
 	/* Install the image */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	status = m_fwu_client->write_stream(stream_handle,
@@ -201,7 +201,7 @@
 	m_dut->boot();
 
 	/* Perform multi-image update transaction */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	/* Install good image for location 0 */
@@ -210,7 +210,7 @@
 	size_t img_size = max_image_size(&uuid);
 	m_dut->generate_image_data(&image_data, img_size);
 
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	status = m_fwu_client->write_stream(stream_handle,
@@ -226,7 +226,7 @@
 	img_size = max_image_size(&uuid) + 1;
 	m_dut->generate_image_data(&image_data, img_size);
 
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	status = m_fwu_client->write_stream(stream_handle,
@@ -242,7 +242,7 @@
 	img_size = max_image_size(&uuid);
 	m_dut->generate_image_data(&image_data, img_size);
 
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	status = m_fwu_client->write_stream(stream_handle,
diff --git a/components/service/fwu/test/ref_scenarios/power_failure_tests.cpp b/components/service/fwu/test/ref_scenarios/power_failure_tests.cpp
index a009e8c..3ee2015 100644
--- a/components/service/fwu/test/ref_scenarios/power_failure_tests.cpp
+++ b/components/service/fwu/test/ref_scenarios/power_failure_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <CppUTest/TestHarness.h>
 #include <vector>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/test/fwu_dut/fwu_dut.h"
 #include "service/fwu/test/fwu_dut_factory/fwu_dut_factory.h"
 /*
@@ -62,7 +62,7 @@
 	m_metadata_checker->check_regular(boot_info.boot_index);
 
 	/* Begin staging */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
@@ -75,13 +75,13 @@
 	m_metadata_checker->check_regular(boot_info.boot_index);
 
 	/* Begin staging again */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
 	/* Start installing an image but don't commit it */
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	m_dut->generate_image_data(&image_data);
@@ -100,13 +100,13 @@
 	m_metadata_checker->check_regular(boot_info.boot_index);
 
 	/* Begin staging again */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
 	/* Start installing an image but this time commit it without ending staging */
 	m_dut->whole_volume_image_type_uuid(1, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	m_dut->generate_image_data(&image_data);
@@ -147,13 +147,13 @@
 	m_metadata_checker->check_regular(boot_info.boot_index);
 
 	/* Begin staging */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
 	/* Install a partial update */
 	m_dut->whole_volume_image_type_uuid(2, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	m_dut->generate_image_data(&image_data);
diff --git a/components/service/fwu/test/ref_scenarios/rollback_tests.cpp b/components/service/fwu/test/ref_scenarios/rollback_tests.cpp
index db77a3f..1222068 100644
--- a/components/service/fwu/test/ref_scenarios/rollback_tests.cpp
+++ b/components/service/fwu/test/ref_scenarios/rollback_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <CppUTest/TestHarness.h>
 #include <vector>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/test/fwu_dut/fwu_dut.h"
 #include "service/fwu/test/fwu_dut_factory/fwu_dut_factory.h"
 
@@ -67,12 +67,12 @@
 	unsigned int pre_update_bank_index = boot_info.boot_index;
 
 	/* Install the update */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	std::vector<uint8_t> image_data;
@@ -132,12 +132,12 @@
 	unsigned int pre_update_bank_index = boot_info.boot_index;
 
 	/* Install the update */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	std::vector<uint8_t> image_data;
@@ -204,12 +204,12 @@
 	unsigned int pre_update_bank_index = boot_info.boot_index;
 
 	/* Install the update */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	std::vector<uint8_t> image_data;
diff --git a/components/service/fwu/test/ref_scenarios/update_fmp_tests.cpp b/components/service/fwu/test/ref_scenarios/update_fmp_tests.cpp
index 310899a..53a96a9 100644
--- a/components/service/fwu/test/ref_scenarios/update_fmp_tests.cpp
+++ b/components/service/fwu/test/ref_scenarios/update_fmp_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,8 +10,8 @@
 #include <vector>
 
 #include "common/uuid/uuid.h"
-#include "protocols/service/fwu/packed-c/fwu_proto.h"
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/fwu_proto.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/test/fwu_dut/fwu_dut.h"
 #include "service/fwu/test/fwu_dut_factory/fwu_dut_factory.h"
 
@@ -92,12 +92,12 @@
 		struct uuid_octets *uuid = &(img_info[ImageIndex].ImageTypeId);
 
 		if (!is_staging) {
-			status = client->begin_staging();
+			status = client->begin_staging(0, 0, NULL);
 			LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 			is_staging = true;
 		}
 
-		status = client->open(uuid, &stream_handle);
+		status = client->open(uuid, fwu_client::op_type::WRITE, &stream_handle);
 		LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 		status = client->write_stream(stream_handle, static_cast<const uint8_t *>(Image),
@@ -118,7 +118,7 @@
 		size_t reported_total_len = 0;
 		struct uuid_octets uuid;
 
-		struct ts_fwu_image_directory *img_dir = NULL;
+		struct fwu_image_directory *img_dir = NULL;
 
 		size_t data_len_read = 0;
 		int num_img = 0;
@@ -127,7 +127,7 @@
 
 		uuid_guid_octets_from_canonical(&uuid, FWU_DIRECTORY_CANONICAL_UUID);
 
-		status = client->open(&uuid, &stream_handle);
+		status = client->open(&uuid, fwu_client::op_type::READ, &stream_handle);
 		LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 		// Determine the size of the FW directory without reading any info.
@@ -139,10 +139,10 @@
 		// to reset the read seek.
 		status = client->commit(stream_handle, false);
 		LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
-		status = client->open(&uuid, &stream_handle);
+		status = client->open(&uuid, fwu_client::op_type::READ, &stream_handle);
 		LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
-		img_dir = (ts_fwu_image_directory *)new uint8_t[reported_total_len];
+		img_dir = (fwu_image_directory *)new uint8_t[reported_total_len];
 
 		// Read the firmware directory info into img_dir.
 		status = client->read_stream(stream_handle, reinterpret_cast<uint8_t *>(img_dir),
diff --git a/components/service/fwu/test/ref_scenarios/update_scenario_tests.cpp b/components/service/fwu/test/ref_scenarios/update_scenario_tests.cpp
index b5c8341..c48eb68 100644
--- a/components/service/fwu/test/ref_scenarios/update_scenario_tests.cpp
+++ b/components/service/fwu/test/ref_scenarios/update_scenario_tests.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #include <CppUTest/TestHarness.h>
 #include <vector>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/test/fwu_dut/fwu_dut.h"
 #include "service/fwu/test/fwu_dut_factory/fwu_dut_factory.h"
 
@@ -40,6 +40,39 @@
 	fwu_client *m_fwu_client;
 };
 
+TEST(FwuUpdateScenarioTests, discover)
+{
+	int16_t service_status = 0;
+	uint8_t version_major = 0;
+	uint8_t version_minor = 0;
+	uint16_t num_func = 0;
+	uint64_t max_payload_size = 0;
+	uint32_t flags = 0;
+	uint32_t vendor_specific_flags = 0;
+	uint8_t function_presence[10] = { 0 };
+	uint8_t expected_functions[10] = { 0, 16, 17, 18, 19, 20, 21, 22, 23, 24 };
+
+	m_dut = fwu_dut_factory::create(1, false);
+	m_fwu_client = m_dut->create_fwu_client();
+	m_metadata_checker = m_dut->create_metadata_checker();
+
+	m_dut->boot();
+
+	int res = m_fwu_client->discover(&service_status, &version_major, &version_minor, &num_func,
+					 &max_payload_size, &flags, &vendor_specific_flags,
+					 function_presence);
+	LONGS_EQUAL(0, res);
+
+	UNSIGNED_LONGS_EQUAL(0, service_status);
+	UNSIGNED_LONGS_EQUAL(1, version_major);
+	UNSIGNED_LONGS_EQUAL(0, version_minor);
+	UNSIGNED_LONGS_EQUAL(10, sizeof(expected_functions));
+	UNSIGNED_LONGS_EQUAL(0, max_payload_size);
+	UNSIGNED_LONGS_EQUAL(0, flags);
+	UNSIGNED_LONGS_EQUAL(0, vendor_specific_flags);
+	MEMCMP_EQUAL(expected_functions, function_presence, sizeof(expected_functions));
+}
+
 TEST(FwuUpdateScenarioTests, wholeFirmwareUpdateFlow)
 {
 	int status = 0;
@@ -67,12 +100,12 @@
 	unsigned int pre_update_bank_index = boot_info.boot_index;
 
 	/* Perform staging steps where a single image is installed */
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	std::vector<uint8_t> image_data;
@@ -152,13 +185,13 @@
 
 	/* Perform staging steps where multiple images are installed */
 	std::vector<uint8_t> image_data;
-	status = m_fwu_client->begin_staging();
+	status = m_fwu_client->begin_staging(0, 0, NULL);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 	m_metadata_checker->check_ready_for_staging(boot_info.boot_index);
 
 	/* Install whole image for location 0 */
 	m_dut->whole_volume_image_type_uuid(0, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	m_dut->generate_image_data(&image_data);
@@ -174,7 +207,7 @@
 
 	/* Install whole image for location 1 */
 	m_dut->whole_volume_image_type_uuid(1, &uuid);
-	status = m_fwu_client->open(&uuid, &stream_handle);
+	status = m_fwu_client->open(&uuid, fwu_client::op_type::WRITE, &stream_handle);
 	LONGS_EQUAL(FWU_STATUS_SUCCESS, status);
 
 	m_dut->generate_image_data(&image_data);
diff --git a/components/service/fwu/test/service/fwu_service_tests.cpp b/components/service/fwu/test/service/fwu_service_tests.cpp
index 0476d92..1624609 100644
--- a/components/service/fwu/test/service/fwu_service_tests.cpp
+++ b/components/service/fwu/test/service/fwu_service_tests.cpp
@@ -7,7 +7,7 @@
 #include <CppUTest/TestHarness.h>
 #include <vector>
 
-#include "protocols/service/fwu/packed-c/status.h"
+#include "protocols/service/fwu/status.h"
 #include "service/fwu/test/fwu_dut/fwu_dut.h"
 #include "service/fwu/test/fwu_dut_factory/fwu_dut_factory.h"
 #include "service/fwu/test/image_directory_checker/image_directory_checker.h"
diff --git a/components/service/locator/interface/service_locator.h b/components/service/locator/interface/service_locator.h
index 87f1f0d..ad01ec1 100644
--- a/components/service/locator/interface/service_locator.h
+++ b/components/service/locator/interface/service_locator.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -7,7 +7,7 @@
 #ifndef SERVICE_LOCATOR_H
 #define SERVICE_LOCATOR_H
 
-#include "components/rpc/common/caller/rpc_caller_session.h"
+#include "rpc_caller_session.h"
 
 /*
  * The service_locator puplic interface may be exported as a public interface to
diff --git a/components/service/locator/sp/ffa/spffa_service_context.c b/components/service/locator/sp/ffa/spffa_service_context.c
index f7730d0..7613162 100644
--- a/components/service/locator/sp/ffa/spffa_service_context.c
+++ b/components/service/locator/sp/ffa/spffa_service_context.c
@@ -19,7 +19,7 @@
 struct sp_ts_service_context *spffa_service_context_create(const struct rpc_uuid *service_uuid)
 {
 	struct sp_ts_service_context *new_context =
-		(struct sp_ts_service_context*)malloc(sizeof(struct sp_ts_service_context));
+		(struct sp_ts_service_context *)calloc(1, sizeof(struct sp_ts_service_context));
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	if (!new_context)
diff --git a/components/service/locator/standalone/services/protected-storage/ps_service_context.cpp b/components/service/locator/standalone/services/protected-storage/ps_service_context.cpp
index edad9df..d17550d 100644
--- a/components/service/locator/standalone/services/protected-storage/ps_service_context.cpp
+++ b/components/service/locator/standalone/services/protected-storage/ps_service_context.cpp
@@ -10,6 +10,7 @@
 #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include "media/disk/guid.h"
 #include <assert.h>
+#include <compiler.h>
 
 ps_service_context::ps_service_context(const char *sn) :
 	standalone_service_context(sn),
@@ -37,7 +38,7 @@
 	m_block_store = client_block_store_factory_create("sn:trustedfirmware.org:block-storage:0");
 	assert(m_block_store != NULL);
 
-	psa_status_t status = sfs_flash_block_store_adapter_init(
+	__maybe_unused psa_status_t status = sfs_flash_block_store_adapter_init(
 		&m_sfs_flash_adapter,
 		0,
 		m_block_store,
diff --git a/components/service/rpmb/backend/mock/test/test_rpmb_backend_mock.cpp b/components/service/rpmb/backend/mock/test/test_rpmb_backend_mock.cpp
index 594ba3c..023f941 100644
--- a/components/service/rpmb/backend/mock/test/test_rpmb_backend_mock.cpp
+++ b/components/service/rpmb/backend/mock/test/test_rpmb_backend_mock.cpp
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
 #include <CppUTest/TestHarness.h>
+#include <CppUTestExt/MockSupport.h>
 #include "../rpmb_backend_mock.h"
 #include <string.h>
 
@@ -17,6 +18,8 @@
 	TEST_TEARDOWN()
 	{
 		rpmb_backend_mock_deinit(&mock_backend);
+		mock().checkExpectations();
+		mock().clear();
 	}
 
 	struct rpmb_backend *backend;
diff --git a/components/service/secure_storage/backend/secure_flash_store/flash_fs/sfs_flash_fs.c b/components/service/secure_storage/backend/secure_flash_store/flash_fs/sfs_flash_fs.c
index d197fa2..af89a65 100644
--- a/components/service/secure_storage/backend/secure_flash_store/flash_fs/sfs_flash_fs.c
+++ b/components/service/secure_storage/backend/secure_flash_store/flash_fs/sfs_flash_fs.c
@@ -96,7 +96,7 @@
 
     /* Check that the file's maximum size is valid */
     if (max_size > fs_ctx->flash_info->max_file_size) {
-        return PSA_ERROR_INVALID_ARGUMENT;
+        return PSA_ERROR_INSUFFICIENT_STORAGE;
     }
 
     /* Check if file already exists */
diff --git a/components/service/secure_storage/backend/secure_flash_store/secure_flash_store.c b/components/service/secure_storage/backend/secure_flash_store/secure_flash_store.c
index 6508b0c..646ed15 100644
--- a/components/service/secure_storage/backend/secure_flash_store/secure_flash_store.c
+++ b/components/service/secure_storage/backend/secure_flash_store/secure_flash_store.c
@@ -7,6 +7,7 @@
 
 #include "flash/sfs_flash.h"
 #include "flash_fs/sfs_flash_fs.h"
+#include <limits.h>
 #include "sfs_utils.h"
 #include "secure_flash_store.h"
 #include <string.h>
@@ -15,20 +16,13 @@
 #define SFS_MAX_ASSET_SIZE (4096) /* TODO: comes from flash layout */
 #define SFS_CREATE_FLASH_LAYOUT /* TODO: move this to a proper place */
 
-#ifndef SFS_BUF_SIZE
-/* By default, set the SFS buffer size to the max asset size so that all
- * requests can be handled in one iteration.
- */
-#define SFS_BUF_SIZE SFS_MAX_ASSET_SIZE
-#endif
-
 #define SFS_INVALID_UID 0 /* TODO: are there any invalid UID-s? */
 
 /* Buffer to store asset data from the caller.
  * Note: size must be aligned to the max flash program unit to meet the
  * alignment requirement of the filesystem.
  */
-static uint8_t asset_data[SFS_UTILS_ALIGN(SFS_BUF_SIZE,
+static uint8_t asset_data[SFS_UTILS_ALIGN(SFS_MAX_ASSET_SIZE,
                                           SFS_FLASH_MAX_ALIGNMENT)];
 
 static uint8_t g_fid[SFS_FILE_ID_SIZE];
@@ -233,7 +227,7 @@
     }
 
     /* Copy file info to the PSA info struct */
-    p_info->capacity = g_file_info.size_current;
+    p_info->capacity = g_file_info.size_max;
     p_info->size = g_file_info.size_current;
     p_info->flags = g_file_info.flags;
 
@@ -277,12 +271,33 @@
                             uint32_t create_flags)
 {
     (void)context;
-    (void)client_id;
-    (void)uid;
-    (void)capacity;
-    (void)create_flags;
 
-    return PSA_ERROR_NOT_SUPPORTED;
+    psa_status_t status;
+
+    /* Check that the UID is valid */
+    if (uid == SFS_INVALID_UID)
+        return PSA_ERROR_INVALID_ARGUMENT;
+
+    /* Check that the create_flags does not contain any unsupported flags */
+    if (create_flags & PSA_STORAGE_FLAG_WRITE_ONCE)
+        return PSA_ERROR_NOT_SUPPORTED;
+
+    /* Set file id */
+    sfs_get_fid(client_id, uid, g_fid);
+
+    /* Read file info */
+    status = sfs_flash_fs_file_get_info(&fs_ctx_sfs, g_fid, &g_file_info);
+
+    if (status == PSA_SUCCESS) {
+        return PSA_ERROR_ALREADY_EXISTS;
+    } else if (status == PSA_ERROR_DOES_NOT_EXIST) {
+        /* Create the file in the file system */
+        status = sfs_flash_fs_file_create(&fs_ctx_sfs, g_fid, capacity,
+                    0, (uint32_t)create_flags,
+                    NULL);
+    }
+
+    return status;
 }
 
 static psa_status_t sfs_set_extended(void *context,
@@ -292,15 +307,47 @@
                             size_t data_length,
                             const void *p_data)
 {
-    /* Optional function not supported by this backend */
-    (void)context;
-    (void)client_id;
-    (void)uid;
-    (void)data_offset;
-    (void)data_length;
-    (void)p_data;
+    psa_status_t status = PSA_SUCCESS;
+    const uint8_t *data = (const uint8_t *)p_data;
 
-    return PSA_ERROR_NOT_SUPPORTED;
+    /* Check that the UID is valid */
+    if (uid == SFS_INVALID_UID)
+        return PSA_ERROR_INVALID_ARGUMENT;
+
+    /* Get file id */
+    sfs_get_fid(client_id, uid, g_fid);
+
+    /* Read file info */
+    status = sfs_flash_fs_file_get_info(&fs_ctx_sfs, g_fid, &g_file_info);
+    if (status != PSA_SUCCESS)
+        return status;
+
+    if (g_file_info.flags & PSA_STORAGE_FLAG_WRITE_ONCE)
+        return PSA_ERROR_NOT_PERMITTED;
+
+    /* Avoid overflow of the inputs */
+    if (SIZE_MAX - data_offset < data_length)
+        return PSA_ERROR_INVALID_ARGUMENT;
+
+    if (sizeof(asset_data) < data_length)
+        return PSA_ERROR_INVALID_ARGUMENT;
+
+    /* Data write must not exceed the file capacity */
+    if (g_file_info.size_max < data_offset + data_length)
+        return PSA_ERROR_INVALID_ARGUMENT;
+
+    /* Write must not create gaps */
+    if (g_file_info.size_current < data_offset)
+        return PSA_ERROR_INVALID_ARGUMENT;
+
+    /* Read asset data from the caller */
+    memcpy(asset_data, data, data_length);
+
+    /* Write to the file in the file system */
+    status = sfs_flash_fs_file_write(&fs_ctx_sfs, g_fid,
+                                     data_length, data_offset, asset_data);
+
+    return status;
 }
 
 static uint32_t sfs_get_support(void *context, uint32_t client_id)
@@ -308,8 +355,7 @@
     (void)context;
     (void)client_id;
 
-    /* No optional functions supported */
-    return 0;
+    return PSA_STORAGE_SUPPORT_SET_EXTENDED;
 }
 
 struct storage_backend *sfs_init(const struct sfs_flash_info_t *flash_binding)
diff --git a/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.c b/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.c
index b94fc41..e2c2112 100644
--- a/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.c
+++ b/components/service/secure_storage/backend/secure_storage_client/secure_storage_client.c
@@ -293,7 +293,7 @@
 	handle = rpc_caller_session_begin(this_context->client.session, &request, request_length,
 					  0);
 	if (!handle)
-		goto out;
+		return PSA_ERROR_INVALID_ARGUMENT;
 
 	/* Populating request descriptor */
 	request_desc = (struct secure_storage_request_set_extended *)request;
@@ -311,7 +311,6 @@
 	if (psa_status == PSA_SUCCESS && rpc_status != RPC_SUCCESS)
 		psa_status = PSA_ERROR_GENERIC_ERROR;
 
-out:
 	return psa_status;
 }
 
diff --git a/components/service/secure_storage/include/psa/internal_trusted_storage.h b/components/service/secure_storage/include/psa/internal_trusted_storage.h
index da69054..9ac7798 100644
--- a/components/service/secure_storage/include/psa/internal_trusted_storage.h
+++ b/components/service/secure_storage/include/psa/internal_trusted_storage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -14,6 +14,12 @@
 extern "C" {
 #endif
 
+#ifdef EXPORT_PUBLIC_INTERFACE_PSA_ITS
+#define PSA_ITS_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define PSA_ITS_EXPORTED
+#endif
+
 /**
  * The major version number of the PSA ITS API. It will be incremented on
  * significant updates that may include breaking changes.
@@ -36,10 +42,9 @@
  *
  * @return     A status indicating the success/failure of the operation
  */
-psa_status_t psa_its_set(psa_storage_uid_t uid,
-			 size_t data_length,
-			 const void *p_data,
-			 psa_storage_create_flags_t create_flags);
+PSA_ITS_EXPORTED psa_status_t psa_its_set(psa_storage_uid_t uid, size_t data_length,
+					  const void *p_data,
+					  psa_storage_create_flags_t create_flags);
 
 /**
  * @brief      Retrieve data associated with a provided UID.
@@ -54,11 +59,8 @@
  *
  * @return     A status indicating the success/failure of the operation
  */
-psa_status_t psa_its_get(psa_storage_uid_t uid,
-			 size_t data_offset,
-			 size_t data_size,
-			 void *p_data,
-			 size_t *p_data_length);
+PSA_ITS_EXPORTED psa_status_t psa_its_get(psa_storage_uid_t uid, size_t data_offset,
+					  size_t data_size, void *p_data, size_t *p_data_length);
 
 /**
  * @brief      Retrieve the metadata about the provided uid.
@@ -69,8 +71,8 @@
  *
  * @return     A status indicating the success/failure of the operation
  */
-psa_status_t psa_its_get_info(psa_storage_uid_t uid,
-			      struct psa_storage_info_t *p_info);
+PSA_ITS_EXPORTED psa_status_t psa_its_get_info(psa_storage_uid_t uid,
+					       struct psa_storage_info_t *p_info);
 
 /**
  * @brief      Remove the provided key and its associated data from the storage
@@ -79,7 +81,7 @@
  *
  * @return     A status indicating the success/failure of the operation
  */
-psa_status_t psa_its_remove(psa_storage_uid_t uid);
+PSA_ITS_EXPORTED psa_status_t psa_its_remove(psa_storage_uid_t uid);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/secure_storage/include/psa/protected_storage.h b/components/service/secure_storage/include/psa/protected_storage.h
index ff827b1..8fa8f4a 100644
--- a/components/service/secure_storage/include/psa/protected_storage.h
+++ b/components/service/secure_storage/include/psa/protected_storage.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -20,13 +20,19 @@
 extern "C" {
 #endif
 
+#ifdef EXPORT_PUBLIC_INTERFACE_PSA_PS
+#define PSA_PS_EXPORTED __attribute__((__visibility__("default")))
+#else
+#define PSA_PS_EXPORTED
+#endif
+
 /**
  * \brief PSA_PS_API_VERSION version
  *
  * Major and minor PSA_PS_API_VERSION numbers
  */
-#define PSA_PS_API_VERSION_MAJOR  1
-#define PSA_PS_API_VERSION_MINOR  0
+#define PSA_PS_API_VERSION_MAJOR 1
+#define PSA_PS_API_VERSION_MINOR 0
 
 // This version of the header file is associated with 1.0 final release
 
@@ -65,10 +71,9 @@
  * \retval PSA_ERROR_GENERIC_ERROR         The operation failed because of an
  *                                         unspecified internal failure
  */
-psa_status_t psa_ps_set(psa_storage_uid_t uid,
-						size_t data_length,
-						const void *p_data,
-						psa_storage_create_flags_t create_flags);
+PSA_PS_EXPORTED psa_status_t psa_ps_set(psa_storage_uid_t uid, size_t data_length,
+					const void *p_data,
+					psa_storage_create_flags_t create_flags);
 
 /**
  * \brief Retrieve data associated with a provided uid
@@ -113,11 +118,8 @@
  *                                     associated with the UID failed
  *                                     authentication
  */
-psa_status_t psa_ps_get(psa_storage_uid_t uid,
-						size_t data_offset,
-						size_t data_size,
-						void *p_data,
-						size_t *p_data_length);
+PSA_PS_EXPORTED psa_status_t psa_ps_get(psa_storage_uid_t uid, size_t data_offset, size_t data_size,
+					void *p_data, size_t *p_data_length);
 
 /**
  * \brief Retrieve the metadata about the provided uid
@@ -145,8 +147,8 @@
  * \retval PSA_ERROR_DATA_CORRUPT      The operation failed because the data
  *                                     associated with the UID was corrupt
  */
-psa_status_t psa_ps_get_info(psa_storage_uid_t uid,
-							 struct psa_storage_info_t *p_info);
+PSA_PS_EXPORTED psa_status_t psa_ps_get_info(psa_storage_uid_t uid,
+					     struct psa_storage_info_t *p_info);
 
 /**
  * \brief Remove the provided uid and its associated data from the storage
@@ -172,7 +174,7 @@
  * \retval PSA_ERROR_GENERIC_ERROR     The operation failed because of an
  *                                     unspecified internal failure
  */
-psa_status_t psa_ps_remove(psa_storage_uid_t uid);
+PSA_PS_EXPORTED psa_status_t psa_ps_remove(psa_storage_uid_t uid);
 
 /**
  * \brief Reserves storage for the specified uid
@@ -207,9 +209,8 @@
  * \retval PSA_ERROR_ALREADY_EXISTS        Storage for the specified uid
  *                                         already exists
  */
-psa_status_t psa_ps_create(psa_storage_uid_t uid,
-						   size_t capacity,
-						   psa_storage_create_flags_t create_flags);
+PSA_PS_EXPORTED psa_status_t psa_ps_create(psa_storage_uid_t uid, size_t capacity,
+					   psa_storage_create_flags_t create_flags);
 
 /**
  * \brief Sets partial data into an asset
@@ -259,10 +260,8 @@
  *                                      with the flag
  *                                      PSA_STORAGE_FLAG_WRITE_ONCE
  */
-psa_status_t psa_ps_set_extended(psa_storage_uid_t uid,
-								 size_t data_offset,
-								 size_t data_length,
-								 const void *p_data);
+PSA_PS_EXPORTED psa_status_t psa_ps_set_extended(psa_storage_uid_t uid, size_t data_offset,
+						 size_t data_length, const void *p_data);
 
 /**
  * \brief Lists optional features.
@@ -273,7 +272,7 @@
  *                                      are limited to
  *                                      PSA_STORAGE_SUPPORT_SET_EXTENDED
  */
-uint32_t psa_ps_get_support(void);
+PSA_PS_EXPORTED uint32_t psa_ps_get_support(void);
 
 #ifdef __cplusplus
 }
diff --git a/components/service/spm_test/sp.c b/components/service/spm_test/sp.c
index 0b75d94..f20a15d 100644
--- a/components/service/spm_test/sp.c
+++ b/components/service/spm_test/sp.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -314,7 +314,7 @@
 	}
 
 	/* Non-null flags (W2) register */
-	ffa_svc(FFA_MSG_SEND_DIRECT_REQ_64, (uint32_t)(src << 16 | 0x1000), 1, 0, 0, 0, 0, 0,
+	ffa_svc(FFA_MSG_SEND_DIRECT_REQ_64, (uint32_t)(src << 16 | dst), 1, 0, 0, 0, 0, 0,
 		&raw_params);
 	if (raw_params.a0 != FFA_ERROR || (uint32_t)raw_params.a2 != FFA_INVALID_PARAMETERS) {
 		EMSG("Unexpected error code: %d != %ld", FFA_INVALID_PARAMETERS, raw_params.a2);
@@ -496,7 +496,13 @@
 				 &out_region_count, handle);
 
 	if (res) {
-		DMSG("Failed retrieving me share");
+		DMSG("Failed retrieving shared memory");
+		return_error((uint32_t)ERR_MEM_RETRIEVE, msg);
+		return;
+	}
+
+	if (descriptor.flags.transaction_type != sp_memory_transaction_type_share) {
+		EMSG("Invalid transaction type");
 		return_error((uint32_t)ERR_MEM_RETRIEVE, msg);
 		return;
 	}
@@ -564,9 +570,7 @@
 
 	res = sp_memory_share(&desc, &acc_desc, 1, &region, 1, &handle);
 	if (res != FFA_OK) {
-		EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to share memory: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -576,9 +580,7 @@
 				      handle >> 32, own_id, 0, msg);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send retrieve command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -588,9 +590,7 @@
 				0, 0, 0, msg);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send TRY_W_ACCESS command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -599,9 +599,7 @@
 				EP_RELINQUISH, handle & 0xffffffff,
 				handle >> 32, 0, 0, msg);
 	if (res != FFA_OK) {
-		EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send relinquish command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -609,9 +607,7 @@
 	res = ffa_mem_reclaim(handle, 0);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to reclaim memory: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -629,7 +625,7 @@
 	uint64_t handle = 0;
 	struct ffa_mem_transaction_buffer t_buf = {0};
 	uint16_t own_id = 0;
-	uint16_t src_id = msg->source_id = 0;
+	uint16_t src_id = msg->source_id;
 	struct sp_memory_access_descriptor acc_desc[2] = { };
 	uint32_t err = 0;
 	uint16_t endpoint2 = msg->args.args64[1];
@@ -659,7 +655,7 @@
 
 	res = sp_memory_share(&desc, acc_desc, 2, &region, 1, &handle);
 	if (res != FFA_OK) {
-		EMSG("ffa_memory_share(): error %"PRId32, res);
+		EMSG("Failed to share memory: %"PRId32, res);
 		err = (uint32_t)ERR_SP_SHARE;
 		goto err;
 	}
@@ -669,9 +665,7 @@
 				      handle >> 32, own_id, 0, msg);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send retrieve command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -681,9 +675,7 @@
 				0, 0, 0, msg);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send TRY_W_ACCESS command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -699,9 +691,7 @@
 				      handle >> 32, 0, 0, msg);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send relinquish command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -712,9 +702,7 @@
 				      handle >> 32, own_id, 0, msg);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send retrieve command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -724,9 +712,7 @@
 				0, 0, 0, msg);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send TRY_W_ACCESS command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
@@ -748,15 +734,13 @@
 				handle >> 32, 0, 0, msg);
 
 	if (res != FFA_OK) {
-		EMSG("test_mem_multi_sharing(): error % in %s:%d"PRId32, res,
-							          __FILE__,
-							          __LINE__);
+		EMSG("Failed to send relinquish command: %"PRId32, res);
 		return_error((uint32_t)ERR_SP_SHARE, msg);
 		return;
 	}
 
 	if (ffa_mem_reclaim(handle, 0) != FFA_OK) {
-		EMSG("All memory should have been relinquished!");
+		EMSG("Failed to reclaim memory: %"PRId32, res);
 		err = (uint32_t)ERR_SP_SHARE;
 		goto err;
 	}
@@ -771,6 +755,104 @@
 	return_error(err, msg);
 }
 
+#define TEST_FFA_MEM_SHARE(len, handle, expected) \
+do { \
+	ffa_result res = FFA_OK; \
+	res = ffa_mem_share_rxtx(len, len, handle); \
+	if (res != expected) { \
+		EMSG("Invalid FFA_MEM_SHARE result: expected = %d, actual = %d", \
+		     expected, res); \
+		return -1; \
+	} \
+} while (0)
+
+static int test_mem_sharing_invalid(uint16_t service_ep_id)
+{
+	uint64_t handle = 0;
+	uint16_t own_id = 0;
+	size_t len = 0;
+	struct ffa_mem_transaction_desc *transaction = NULL;
+	struct ffa_mem_access_desc *acc_desc = NULL;
+	struct ffa_composite_mem_region_desc *comp_desc = NULL;
+	struct ffa_constituent_mem_region_desc *region = NULL;
+
+	memset((void *)tx_buffer, 0x00, sizeof(tx_buffer));
+
+	transaction = (struct ffa_mem_transaction_desc *)tx_buffer;
+
+	ffa_id_get(&own_id);
+
+	transaction->sender_id = own_id;
+	transaction->mem_region_attr = 0x24;
+	transaction->flags = 0;
+	transaction->handle = 0;
+	transaction->tag = 0;
+
+	len = sizeof(*transaction);
+
+	/* Zero offset, size and count */
+	TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	/* Zero count */
+	transaction->mem_access_desc_size = sizeof(struct ffa_mem_access_desc);
+	transaction->mem_access_desc_offset = sizeof(*transaction);
+#endif /* CFG_FFA_VERSION */
+
+	/* Too many mem access desc */
+	transaction->mem_access_desc_count = sizeof(tx_buffer);
+	TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+	transaction->mem_access_desc_count = 1;
+
+#if CFG_FFA_VERSION >= FFA_VERSION_1_1
+	/* Invalid offset */
+	transaction->mem_access_desc_offset = sizeof(tx_buffer);
+	TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+	transaction->mem_access_desc_offset = sizeof(*transaction);
+#endif /* CFG_FFA_VERSION */
+
+	acc_desc = (struct ffa_mem_access_desc *)(tx_buffer + len);
+	len +=  sizeof(*acc_desc);
+
+	acc_desc->mem_access_perm_desc.endpoint_id = service_ep_id;
+	acc_desc->mem_access_perm_desc.mem_access_permissions = 0x06; /* RWnX */
+
+	/* Too large memory region descriptor offset */
+	acc_desc->composite_mem_region_desc_offset = sizeof(tx_buffer);
+	TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+	acc_desc->composite_mem_region_desc_offset = len;
+	comp_desc = (struct ffa_composite_mem_region_desc *)(tx_buffer + len);
+	len += sizeof(*comp_desc);
+
+	/* Zero pages and address ranges */
+	TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+	region = (struct ffa_constituent_mem_region_desc *)(tx_buffer + len);
+	len += sizeof(*region);
+
+	/* One region with zero pages */
+	region->address = (uint64_t)shared_buffer;
+	comp_desc->address_range_count = 1;
+	TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+	/* One region with not matching sum pages */
+	region->address = (uint64_t)shared_buffer;
+	comp_desc->address_range_count = 1;
+	comp_desc->total_page_count = 2;
+	region->page_count = 1;
+	TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+	/* Too many regions */
+	comp_desc->total_page_count = sizeof(tx_buffer);
+	comp_desc->address_range_count = sizeof(tx_buffer);
+	TEST_FFA_MEM_SHARE(len, &handle, FFA_INVALID_PARAMETERS);
+
+	return 0;
+}
+
 static void test_mem_sharing_inccorrect_access(uint16_t service_ep_id,
 					struct ffa_direct_msg *msg)
 {
@@ -780,7 +862,7 @@
 	uint64_t handle = 0;
 	struct ffa_mem_transaction_buffer t_buf = {0};
 	uint16_t own_id = 0;
-	uint16_t src_id = msg->source_id = 0;
+	uint16_t src_id = msg->source_id;
 	struct sp_memory_access_descriptor acc_desc = { };
 
 	set_rxtx_buf(&t_buf, NULL);
@@ -807,6 +889,11 @@
 		return;
 	}
 
+	if (test_mem_sharing_invalid(service_ep_id)) {
+		return_error((uint32_t)ERR_SP_SHARE, msg);
+		return;
+	}
+
 	msg->destination_id = own_id;
 	msg->source_id = src_id;
 	return_ok(msg);
@@ -822,7 +909,7 @@
 	uint64_t handle2 = 0;
 	struct ffa_mem_transaction_buffer t_buf = {0};
 	uint16_t own_id = 0;
-	uint16_t src_id = msg->source_id = 0;
+	uint16_t src_id = msg->source_id;
 	struct sp_memory_access_descriptor acc_desc = { };
 	uint32_t err = 0;
 
@@ -1029,3 +1116,19 @@
 	(void)interrupt_id;
 	DMSG("Got interrupt %x", interrupt_id);
 }
+
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)handle;
+	DMSG("VM with ID %d created", vm_id);
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)handle;
+	DMSG("VM with ID %d destroyed", vm_id);
+
+	return FFA_OK;
+}
diff --git a/components/service/spm_test/spm_test.cmake b/components/service/spm_test/spm_test.cmake
index 17cca5a..ed81d5f 100644
--- a/components/service/spm_test/spm_test.cmake
+++ b/components/service/spm_test/spm_test.cmake
@@ -58,7 +58,6 @@
 endif()
 
 install(TARGETS spm-test${SP_NUMBER}
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c b/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c
index 27a22cb..c42586f 100644
--- a/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c
+++ b/components/service/test_runner/provider/backend/simple_c/simple_c_test_runner.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -101,11 +101,22 @@
                     if (summary->num_tests < result_limit) {
 
                         struct test_result *new_result = &results[summary->num_results];
+			size_t len = 0;
 
                         new_result->run_state = run_state;
                         new_result->failure = failure;
-                        strcpy(new_result->group, test_group->group);
-                        strcpy(new_result->name, test_case->name);
+
+			len = strlen(test_group->group) + 1;
+			if (len > sizeof(new_result->group))
+				return -1;
+
+			memcpy(new_result->group, test_group->group, len);
+
+			len = strlen(test_case->name) + 1;
+			if (len > sizeof(new_result->name))
+				return -1;
+
+			memcpy(new_result->name, test_case->name, len);
 
                         ++summary->num_results;
                     }
diff --git a/components/service/uefi/smm_variable/backend/direct/uefi_direct_backend.c b/components/service/uefi/smm_variable/backend/direct/uefi_direct_backend.c
index bf978c5..aed3b9d 100644
--- a/components/service/uefi/smm_variable/backend/direct/uefi_direct_backend.c
+++ b/components/service/uefi/smm_variable/backend/direct/uefi_direct_backend.c
@@ -8,7 +8,11 @@
 #include <mbedtls/build_info.h>
 #include <mbedtls/pkcs7.h>
 #include <mbedtls/x509_crt.h>
+#include "common/mbedtls/mbedtls_utils.h"
+#include <protocols/common/efi/efi_status.h>
 #include <stdint.h>
+#include <string.h>
+#include <compiler.h>
 
 int verify_pkcs7_signature(const uint8_t *signature_cert, uint64_t signature_cert_len,
 			   const uint8_t *hash, uint64_t hash_len, const uint8_t *public_key_cert,
@@ -16,33 +20,115 @@
 {
 	int mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
 
-	/* Parse the public key certificate */
-	mbedtls_x509_crt signer_certificate;
+	/* Parse the PKCS#7 DER encoded signature block */
+	mbedtls_pkcs7 pkcs7_structure;
 
-	mbedtls_x509_crt_init(&signer_certificate);
+	mbedtls_pkcs7_init(&pkcs7_structure);
 
-	mbedtls_status = mbedtls_x509_crt_parse_der(&signer_certificate, public_key_cert,
-						    public_key_cert_len);
+	mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
+							signature_cert_len);
 
-	if (mbedtls_status == 0) {
-		/* Parse the PKCS#7 DER encoded signature block */
-		mbedtls_pkcs7 pkcs7_structure;
+	if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
 
-		mbedtls_pkcs7_init(&pkcs7_structure);
+		/*
+		 * If a separate public key is provided, verify the signature with it,
+		 * else use the key from the pkcs7 signature structure, because it is
+		 * a self-signed certificate.
+		 */
+		if(public_key_cert_len) {
+			/* Parse the public key certificate */
+			mbedtls_x509_crt signer_certificate;
 
-		mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
-							 signature_cert_len);
+			mbedtls_x509_crt_init(&signer_certificate);
 
-		if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
-			/* Verify hash against signed hash */
+			mbedtls_status = mbedtls_x509_crt_parse_der(&signer_certificate, public_key_cert,
+								public_key_cert_len);
+
+			if (mbedtls_status == 0) {
+				/* Verify hash against signed hash */
+				mbedtls_status = mbedtls_pkcs7_signed_hash_verify(
+					&pkcs7_structure, &signer_certificate, hash, hash_len);
+			}
+
+			mbedtls_x509_crt_free(&signer_certificate);
+		} else {
 			mbedtls_status = mbedtls_pkcs7_signed_hash_verify(
-				&pkcs7_structure, &signer_certificate, hash, hash_len);
+				&pkcs7_structure, &pkcs7_structure.private_signed_data.private_certs, hash, hash_len);
 		}
-
-		mbedtls_pkcs7_free(&pkcs7_structure);
 	}
 
-	mbedtls_x509_crt_free(&signer_certificate);
+	mbedtls_pkcs7_free(&pkcs7_structure);
 
 	return mbedtls_status;
 }
+
+int get_uefi_priv_auth_var_fingerprint_handler(const uint8_t *signature_cert,
+				    uint64_t signature_cert_len,
+				    uint8_t *output)
+{
+	int mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+
+	/* Parse the PKCS#7 DER encoded signature block */
+	mbedtls_pkcs7 pkcs7_structure;
+
+	mbedtls_pkcs7_init(&pkcs7_structure);
+
+	mbedtls_status = mbedtls_pkcs7_parse_der(&pkcs7_structure, signature_cert,
+							signature_cert_len);
+
+	if (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) {
+
+		//uint8_t output_buffer[PSA_HASH_MAX_SIZE] =  { 0 };
+		size_t __maybe_unused output_size = 0;
+		const mbedtls_asn1_buf *signerCertCN = NULL;
+		const mbedtls_x509_crt *topLevelCert = &pkcs7_structure.private_signed_data.private_certs;
+		const mbedtls_x509_buf *toplevelCertTbs = NULL;
+		psa_hash_operation_t op = PSA_HASH_OPERATION_INIT;
+
+		/* Find common name field of the signing certificate, which is the first in the chain */
+		signerCertCN = findCommonName(&topLevelCert->subject);
+		if (!signerCertCN) {
+			mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+			goto end;
+		}
+
+		/* Get the TopLevel certificate which is the last in the chain */
+		while(topLevelCert->next)
+			topLevelCert = topLevelCert->next;
+		toplevelCertTbs = &topLevelCert->tbs;
+
+		/* Hash the data to create the fingerprint */
+		op = psa_hash_operation_init();
+
+		if (psa_hash_setup(&op, PSA_ALG_SHA_256) != PSA_SUCCESS) {
+			mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+			goto end;
+		}
+
+		if (psa_hash_update(&op, signerCertCN->p, signerCertCN->len)) {
+			psa_hash_abort(&op);
+			mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+			goto end;
+		}
+
+		if (psa_hash_update(&op, toplevelCertTbs->p, toplevelCertTbs->len)) {
+			psa_hash_abort(&op);
+			mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+			goto end;
+		}
+
+		if (psa_hash_finish(&op, output, PSA_HASH_MAX_SIZE, &output_size)) {
+			psa_hash_abort(&op);
+			mbedtls_status = MBEDTLS_ERR_PKCS7_VERIFY_FAIL;
+			goto end;
+		}
+
+		/* Clear the remaining part of the buffer for consistency */
+		memset(output + output_size, 0, PSA_HASH_MAX_SIZE - output_size);
+	}
+
+end:
+	mbedtls_pkcs7_free(&pkcs7_structure);
+
+	return (mbedtls_status == MBEDTLS_PKCS7_SIGNED_DATA) ? EFI_SUCCESS : EFI_COMPROMISED_DATA;
+}
diff --git a/components/service/uefi/smm_variable/backend/test/variable_index_tests.cpp b/components/service/uefi/smm_variable/backend/test/variable_index_tests.cpp
index 1b7a6b8..cf0f6a1 100644
--- a/components/service/uefi/smm_variable/backend/test/variable_index_tests.cpp
+++ b/components/service/uefi/smm_variable/backend/test/variable_index_tests.cpp
@@ -208,27 +208,43 @@
 
 TEST(UefiVariableIndexTests, dumpLoadRoadtrip)
 {
-	uint8_t buffer[MAX_VARIABLES * sizeof(struct variable_metadata)];
+	uint8_t buffer[sizeof(uint32_t) +
+		       MAX_VARIABLES * (sizeof(struct variable_metadata) + sizeof(bool))];
 
 	create_variables();
 
 	/* Expect the info for two NV variables to have been dumped */
 	size_t dump_len = 0;
-	bool is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len);
+	bool is_dirty = false;
+	efi_status_t status = EFI_SUCCESS;
+
+	status = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len,
+				     &is_dirty);
 
 	CHECK_TRUE(is_dirty);
-	UNSIGNED_LONGS_EQUAL((sizeof(struct variable_metadata) * 2), dump_len);
+	UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status);
+	/*
+	 * Variable index counter is at the beginning, which is followed by metadata and
+	 * constraint status byte of both NV variables
+	 */
+	UNSIGNED_LONGS_EQUAL(sizeof(uint32_t) +
+				     ((sizeof(struct variable_metadata) + sizeof(bool)) * 2),
+			     dump_len);
 
 	/* Expect no records to be dirty when the dump is repeated */
 	dump_len = 0;
-	is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len);
+	status = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len,
+				     &is_dirty);
 
+	UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status);
 	CHECK_FALSE(is_dirty);
-	UNSIGNED_LONGS_EQUAL((sizeof(struct variable_metadata) * 2), dump_len);
+	UNSIGNED_LONGS_EQUAL(sizeof(uint32_t) +
+				     ((sizeof(struct variable_metadata) + sizeof(bool)) * 2),
+			     dump_len);
 
 	/* Tear down and reinitialize to simulate a reboot */
 	variable_index_deinit(&m_variable_index);
-	efi_status_t status = variable_index_init(&m_variable_index, MAX_VARIABLES);
+	status = variable_index_init(&m_variable_index, MAX_VARIABLES);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 
 	/* Load the dumped contents */
@@ -261,9 +277,65 @@
 	UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
 }
 
+TEST(UefiVariableIndexTests, dumpLoadConstrainedVariable)
+{
+	uint8_t buffer[sizeof(uint32_t) +
+		       MAX_VARIABLES * (sizeof(struct variable_metadata) + sizeof(bool))];
+
+	create_variables();
+
+	struct variable_constraints constraints;
+	constraints.revision = 10;
+	constraints.property = VAR_CHECK_VARIABLE_PROPERTY_READ_ONLY;
+	constraints.attributes = 0;
+	constraints.min_size = 1;
+	constraints.max_size = 100;
+
+	/* Set check constraints on one of the variables */
+	struct variable_info *info = variable_index_find(&m_variable_index, &guid_2,
+							 string_get_size_in_bytes(name_2),
+							 (const int16_t *)name_2.data());
+
+	CHECK_TRUE(info);
+	CHECK_TRUE(info->is_variable_set);
+	CHECK_FALSE(info->is_constraints_set);
+
+	variable_index_set_constraints(info, &constraints);
+
+	CHECK_TRUE(info->is_constraints_set);
+	CHECK_TRUE(info->is_variable_set);
+
+	size_t dump_len = 0;
+	bool is_dirty = false;
+	efi_status_t status = EFI_SUCCESS;
+	status = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len,
+				     &is_dirty);
+
+	UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status);
+	CHECK_TRUE(is_dirty);
+
+	/*
+	 * Variable index counter is at the beginning, which is followed by metadata and
+	 * constraint status byte of both NV variables, but only one of them has
+	 * constraints
+	 */
+	UNSIGNED_LONGS_EQUAL(sizeof(uint32_t) +
+				     (sizeof(struct variable_metadata) + sizeof(bool)) * 2 +
+				     sizeof(struct variable_constraints),
+			     dump_len);
+
+	/* Load the dumped contents */
+	size_t load_len = variable_index_restore(&m_variable_index, dump_len, buffer);
+	UNSIGNED_LONGS_EQUAL(dump_len, load_len);
+}
+
 TEST(UefiVariableIndexTests, dumpBufferTooSmall)
 {
-	uint8_t buffer[1 * sizeof(struct variable_metadata) + 1];
+	/*
+	 * Enough to fit the variable index counter and the metadata and constraint
+	 * status of a single variable
+	 */
+	uint8_t buffer[sizeof(uint32_t) + sizeof(struct variable_metadata) + sizeof(bool)];
 
 	create_variables();
 
@@ -272,15 +344,21 @@
 	 * exceed the length of the buffer.
 	 */
 	size_t dump_len = 0;
-	bool is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len);
+	bool is_dirty = false;
+	efi_status_t status = EFI_SUCCESS;
+
+	status = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len,
+				     &is_dirty);
 
 	CHECK_TRUE(is_dirty);
-	UNSIGNED_LONGS_EQUAL(sizeof(struct variable_metadata) * 1, dump_len);
+	UNSIGNED_LONGS_EQUAL(EFI_BUFFER_TOO_SMALL, status);
+	UNSIGNED_LONGS_EQUAL(0, dump_len);
 }
 
 TEST(UefiVariableIndexTests, removeVariable)
 {
-	uint8_t buffer[MAX_VARIABLES * sizeof(struct variable_metadata)];
+	uint8_t buffer[sizeof(uint32_t) +
+		       MAX_VARIABLES * (sizeof(struct variable_metadata) + sizeof(bool))];
 	struct variable_info *info = NULL;
 
 	create_variables();
@@ -293,10 +371,19 @@
 
 	/* Expect index to be dirty and for only one NV variable to be left */
 	size_t dump_len = 0;
-	bool is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len);
+	bool is_dirty = false;
+	efi_status_t status = EFI_SUCCESS;
+	status = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len,
+				     &is_dirty);
 
 	CHECK_TRUE(is_dirty);
-	UNSIGNED_LONGS_EQUAL((sizeof(struct variable_metadata) * 1), dump_len);
+	UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status);
+	/*
+	 * Dump to now contains the variable index counter and metadata,
+	 * constraint status data of a variable
+	 */
+	UNSIGNED_LONGS_EQUAL(sizeof(uint32_t) + sizeof(struct variable_metadata) + sizeof(bool),
+			     dump_len);
 
 	/* Remove the volatile variable */
 	info = variable_index_find(&m_variable_index, &guid_1, string_get_size_in_bytes(name_1),
@@ -306,10 +393,13 @@
 
 	/* Expect index not to be dirty because there was no change to any NV variable */
 	dump_len = 0;
-	is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len);
+	status = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len,
+				     &is_dirty);
 
 	CHECK_FALSE(is_dirty);
-	UNSIGNED_LONGS_EQUAL((sizeof(struct variable_metadata) * 1), dump_len);
+	UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status);
+	UNSIGNED_LONGS_EQUAL(sizeof(uint32_t) + sizeof(struct variable_metadata) + sizeof(bool),
+			     dump_len);
 
 	/* Remove the remaining NV variable */
 	info = variable_index_find(&m_variable_index, &guid_1, string_get_size_in_bytes(name_3),
@@ -317,16 +407,17 @@
 
 	variable_index_clear_variable(&m_variable_index, info);
 
-	/* Expect index to be dirty and dump to now be empty */
+	/* Expect index to be dirty and dump to now contains only the variable index counter */
 	dump_len = 0;
-	is_dirty = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len);
+	status = variable_index_dump(&m_variable_index, sizeof(buffer), buffer, &dump_len,
+				     &is_dirty);
 
 	CHECK_TRUE(is_dirty);
-	UNSIGNED_LONGS_EQUAL((sizeof(struct variable_metadata) * 0), dump_len);
+	UNSIGNED_LONGS_EQUAL(EFI_SUCCESS, status);
+	UNSIGNED_LONGS_EQUAL(sizeof(uint32_t), dump_len);
 
 	/* Enumerate and now expect an empty index */
 	info = NULL;
-	efi_status_t status = EFI_SUCCESS;
 
 	info = variable_index_find_next(&m_variable_index, &guid_1,
 					string_get_size_in_bytes(null_name),  (const int16_t *) null_name.data(),
diff --git a/components/service/uefi/smm_variable/backend/test/variable_store_tests.cpp b/components/service/uefi/smm_variable/backend/test/variable_store_tests.cpp
index fd48f13..0f962f2 100644
--- a/components/service/uefi/smm_variable/backend/test/variable_store_tests.cpp
+++ b/components/service/uefi/smm_variable/backend/test/variable_store_tests.cpp
@@ -5,6 +5,7 @@
  */
 
 #include <CppUTest/TestHarness.h>
+#include <limits>
 #include <service/secure_storage/backend/mock_store/mock_store.h>
 #include <service/uefi/smm_variable/backend/uefi_variable_store.h>
 #include <string.h>
@@ -56,6 +57,12 @@
 		return var_name;
 	}
 
+	std::u16string intToChar16(const int i)
+	{
+		auto s = std::to_string(i);
+		return { s.begin(), s.end() };
+	}
+
 	size_t string_get_size_in_bytes(const std::u16string &string)
 	{
 		return string.size() * sizeof(uint16_t);
@@ -260,12 +267,26 @@
 						       MAX_VARIABLE_SIZE);
 	}
 
-	static const size_t MAX_VARIABLES = 10;
+	static const size_t MAX_VARIABLES = 5;
 	static const size_t MAX_VARIABLE_SIZE = 3000;
-	static const size_t STORE_CAPACITY = 10000;
+	static const size_t STORE_CAPACITY = MAX_VARIABLES * MAX_VARIABLE_SIZE;
+	static const size_t VARIABLE_INDEX_MAX_SIZE =
+		sizeof(uint32_t) +
+		MAX_VARIABLES * (sizeof(struct variable_metadata) +
+				 sizeof(struct variable_constraints) + sizeof(bool));
 
 	static const uint32_t OWNER_ID = 100;
-	static const size_t VARIABLE_BUFFER_SIZE = 1024;
+
+	/* Synchronize these with the variables with the store */
+	uint64_t DEFAULT_VARIABLE_INDEX_STORAGE_A_UID = 0x8000000000000001;
+	uint64_t DEFAULT_VARIABLE_INDEX_STORAGE_B_UID = 0x8000000000000002;
+
+	/*
+	 * Make sure the variable buffer in the test is way above the limit
+	 * so the buffer problems will be handled by the component
+	 * under test.
+	 */
+	static const size_t VARIABLE_BUFFER_SIZE = MAX_VARIABLE_SIZE * 2;
 
 	struct uefi_variable_store m_uefi_variable_store;
 	struct mock_store m_persistent_store;
@@ -501,15 +522,13 @@
 	std::vector<uint8_t> msg_buffer(VARIABLE_BUFFER_SIZE);
 	SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *next_name =
 		(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) msg_buffer.data();
-	size_t max_name_len =
-		VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 
 	size_t total_len = 0;
-	next_name->NameSize = sizeof(int16_t);
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	next_name->Name[0] = 0;
 
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 
 	UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
 }
@@ -574,47 +593,48 @@
 	std::vector<uint8_t> msg_buffer(VARIABLE_BUFFER_SIZE);
 	SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *next_name =
 		(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) msg_buffer.data();
-	size_t max_name_len =
-		VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 
 	/* First check handling of invalid variable name */
 	std::u16string bogus_name = to_variable_name(u"bogus_variable");
 	size_t bogus_name_size = string_get_size_in_bytes(bogus_name);
 	next_name->Guid = m_common_guid;
-	next_name->NameSize = bogus_name_size;
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	memcpy(next_name->Name, bogus_name.data(), bogus_name_size);
 
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_INVALID_PARAMETER, status);
 
 	/* Enumerate store contents */
 	next_name->NameSize = sizeof(int16_t);
 	next_name->Name[0] = 0;
-	/* Check if the correct NameSize is returned if max_name_len is too small */
+	/* Check if the correct NameSize is returned if namesize is too small */
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    0, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_BUFFER_TOO_SMALL, status);
 	UNSIGNED_LONGLONGS_EQUAL(sizeof(var_name_1), next_name->NameSize);
 
-	/* And then used the previously received next_name->NameSize as max_name_len */
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    next_name->NameSize, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 	CHECK_TRUE(compare_variable_name(var_name_1, next_name->Name, next_name->NameSize));
 
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 	CHECK_TRUE(compare_variable_name(var_name_2, next_name->Name, next_name->NameSize));
 
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 	CHECK_TRUE(compare_variable_name(var_name_3, next_name->Name, next_name->NameSize));
 
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
 
 	power_cycle();
@@ -622,21 +642,23 @@
 	/* Enumerate again - should be left with just NV variables.
 	 * Use a different but equally valid null name.
 	 */
-	next_name->NameSize = 10 * sizeof(int16_t);
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	memset(next_name->Name, 0, next_name->NameSize);
 
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 	CHECK_TRUE(compare_variable_name(var_name_1, next_name->Name, next_name->NameSize));
 
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 	CHECK_TRUE(compare_variable_name(var_name_3, next_name->Name, next_name->NameSize));
 
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
 }
 
@@ -672,21 +694,20 @@
 	std::vector<uint8_t> msg_buffer(VARIABLE_BUFFER_SIZE);
 	SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *next_name =
 		(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *) msg_buffer.data();
-	size_t max_name_len =
-		VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 
 	/* Enumerate store contents */
 	size_t total_len = 0;
-	next_name->NameSize = sizeof(int16_t);
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	next_name->Name[0] = 0;
 
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 	CHECK_TRUE(compare_variable_name(var_name_1, next_name->Name, next_name->NameSize));
 
+	next_name->NameSize = VARIABLE_BUFFER_SIZE - SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_NAME_OFFSET;
 	status = uefi_variable_store_get_next_variable_name(&m_uefi_variable_store, next_name,
-							    max_name_len, &total_len);
+							    &total_len);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
 }
 
@@ -762,3 +783,249 @@
 			      EFI_VARIABLE_NON_VOLATILE);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_INVALID_PARAMETER, status);
 }
+
+TEST(UefiVariableStoreTests, fillStore)
+{
+	efi_status_t status = EFI_SUCCESS;
+
+	/* Fill the variable store with max size variables */
+	for (size_t i = 0; i < MAX_VARIABLES; i++) {
+		std::u16string current_var = u"var_";
+		std::string input_data(MAX_VARIABLE_SIZE, 'a');
+		std::string output_data;
+		current_var += intToChar16(i);
+
+		status = set_variable(current_var, input_data,
+				      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+					      EFI_VARIABLE_RUNTIME_ACCESS);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+		/* Verify the write */
+		status = get_variable(current_var, output_data);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+		/* Expect got variable data to be the same as the set value */
+		UNSIGNED_LONGLONGS_EQUAL(input_data.size(), output_data.size());
+		LONGS_EQUAL(0, input_data.compare(output_data));
+	}
+
+	/* Try adding a small variable to an already full store */
+	status = set_variable(u"var", "a",
+			      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+				      EFI_VARIABLE_RUNTIME_ACCESS);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_OUT_OF_RESOURCES, status);
+}
+
+TEST(UefiVariableStoreTests, fillIndex)
+{
+	efi_status_t status = EFI_SUCCESS;
+	std::u16string var_name = u"var";
+	std::string input_data = "a";
+	std::string output_data;
+
+	/*
+	 * Fill the variable store with small variables so the index
+	 * will be filled, but the store does not
+	 */
+	for (size_t i = 0; i < MAX_VARIABLES; i++) {
+		std::u16string current_var = u"var_";
+		current_var += intToChar16(i);
+
+		status = set_variable(current_var, input_data,
+				      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+					      EFI_VARIABLE_RUNTIME_ACCESS);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+		/* Verify the write */
+		status = get_variable(current_var, output_data);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+		/* Expect got variable data to be the same as the set value */
+		UNSIGNED_LONGLONGS_EQUAL(input_data.size(), output_data.size());
+		LONGS_EQUAL(0, input_data.compare(output_data));
+	}
+
+	/* Try adding a small variable to an already full store */
+	input_data.resize(1, 'a');
+
+	status = set_variable(u"var", input_data,
+			      EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+				      EFI_VARIABLE_RUNTIME_ACCESS);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_OUT_OF_RESOURCES, status);
+
+	/* Simulate a power-cycle without deleting the NV store content */
+	uefi_variable_store_deinit(&m_uefi_variable_store);
+
+	/* Try loading the non-volatile variables */
+	status = uefi_variable_store_init(&m_uefi_variable_store, OWNER_ID, MAX_VARIABLES,
+					  m_persistent_backend, m_volatile_backend);
+
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+	/* Try reading the previously set variables */
+	for (size_t i = 0; i < MAX_VARIABLES; i++) {
+		std::u16string current_var = u"var_";
+		current_var += intToChar16(i);
+
+		status = get_variable(current_var, output_data);
+		UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+		UNSIGNED_LONGLONGS_EQUAL(input_data.size(), output_data.size());
+		LONGS_EQUAL(0, input_data.compare(output_data));
+	}
+}
+
+TEST(UefiVariableStoreTests, variableIndexCounterOverflow)
+{
+	efi_status_t efi_status = EFI_SUCCESS;
+	psa_status_t psa_status = PSA_SUCCESS;
+	std::u16string var_name = u"var";
+	std::string input_data = "a";
+	uint32_t attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS |
+			      EFI_VARIABLE_RUNTIME_ACCESS;
+	/* There are no variables set in the index, only the counter is there */
+	uint8_t buffer[sizeof(uint32_t)] = { 0 };
+
+	mock_store_reset(&m_persistent_store);
+
+	/* Counter of index A is 0 */
+	psa_status = m_persistent_store.backend.interface->set(
+		m_persistent_store.backend.context, OWNER_ID, DEFAULT_VARIABLE_INDEX_STORAGE_A_UID,
+		sizeof(buffer), &buffer, PSA_STORAGE_FLAG_NONE);
+	UNSIGNED_LONGLONGS_EQUAL(PSA_SUCCESS, psa_status);
+
+	/* Set max counter value */
+	buffer[0] = 0xFF;
+	buffer[1] = 0xFF;
+	buffer[2] = 0xFF;
+	buffer[3] = 0xFF;
+
+	/* Counter of index B is max value */
+	psa_status = m_persistent_store.backend.interface->set(
+		m_persistent_store.backend.context, OWNER_ID, DEFAULT_VARIABLE_INDEX_STORAGE_B_UID,
+		sizeof(buffer), &buffer, PSA_STORAGE_FLAG_NONE);
+	UNSIGNED_LONGLONGS_EQUAL(PSA_SUCCESS, psa_status);
+
+	/* At next initialization of the store index A should be the latest index with counter value 0 */
+	uefi_variable_store_deinit(&m_uefi_variable_store);
+
+	efi_status = uefi_variable_store_init(&m_uefi_variable_store, OWNER_ID, MAX_VARIABLES,
+					      m_persistent_backend, m_volatile_backend);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.active_variable_index_uid,
+				 DEFAULT_VARIABLE_INDEX_STORAGE_A_UID);
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.variable_index.counter, 0);
+
+	/* After setting a variable to trigger sync and rebooting index B should be the latest index with counter value 1*/
+	efi_status = set_variable(var_name, input_data, attributes);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
+
+	power_cycle();
+
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.active_variable_index_uid,
+				 DEFAULT_VARIABLE_INDEX_STORAGE_B_UID);
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.variable_index.counter, 1);
+}
+
+TEST(UefiVariableStoreTests, oneEmptyVariableIndexExists)
+{
+	psa_status_t status = PSA_SUCCESS;
+
+	/* Only, variable index A exists, but it is empty */
+	mock_store_reset(&m_persistent_store);
+
+	status = m_persistent_store.backend.interface->create(m_persistent_store.backend.context,
+							      OWNER_ID,
+							      DEFAULT_VARIABLE_INDEX_STORAGE_A_UID,
+							      100, PSA_STORAGE_FLAG_NONE);
+	UNSIGNED_LONGLONGS_EQUAL(PSA_SUCCESS, status);
+
+	power_cycle();
+
+	/* Empty index is considered non-existing so default index (A) is selected */
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.active_variable_index_uid,
+				 DEFAULT_VARIABLE_INDEX_STORAGE_A_UID);
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.variable_index.counter, 0);
+
+	/* Only, variable index B exists, but it is empty*/
+	mock_store_reset(&m_persistent_store);
+
+	status = m_persistent_store.backend.interface->create(m_persistent_store.backend.context,
+							      OWNER_ID,
+							      DEFAULT_VARIABLE_INDEX_STORAGE_B_UID,
+							      100, PSA_STORAGE_FLAG_NONE);
+	UNSIGNED_LONGLONGS_EQUAL(PSA_SUCCESS, status);
+
+	power_cycle();
+
+	/* Empty index is considered non-existing so default index (A) is selected */
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.active_variable_index_uid,
+				 DEFAULT_VARIABLE_INDEX_STORAGE_A_UID);
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.variable_index.counter, 0);
+}
+
+TEST(UefiVariableStoreTests, oneVariableIndexAlreadySet)
+{
+	efi_status_t status = EFI_SUCCESS;
+	/* Empty variable index with zero counter value */
+	uint8_t buffer[VARIABLE_INDEX_MAX_SIZE] = { 0 };
+
+	/* Set index A in the store with some data, so it will be found as the currently active index */
+	mock_store_reset(&m_persistent_store);
+
+	status = m_persistent_store.backend.interface->set(
+		m_persistent_store.backend.context, OWNER_ID, DEFAULT_VARIABLE_INDEX_STORAGE_A_UID,
+		sizeof(buffer), &buffer, PSA_STORAGE_FLAG_NONE);
+	UNSIGNED_LONGLONGS_EQUAL(PSA_SUCCESS, status);
+
+	power_cycle();
+
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.active_variable_index_uid,
+				 DEFAULT_VARIABLE_INDEX_STORAGE_A_UID);
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.variable_index.counter, 0);
+
+	/* Set index B in the store with some data, so it will be found as the currently active index */
+	mock_store_reset(&m_persistent_store);
+
+	status = m_persistent_store.backend.interface->set(
+		m_persistent_store.backend.context, OWNER_ID, DEFAULT_VARIABLE_INDEX_STORAGE_B_UID,
+		sizeof(buffer), &buffer, PSA_STORAGE_FLAG_NONE);
+	UNSIGNED_LONGLONGS_EQUAL(PSA_SUCCESS, status);
+
+	power_cycle();
+
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.active_variable_index_uid,
+				 DEFAULT_VARIABLE_INDEX_STORAGE_B_UID);
+	UNSIGNED_LONGLONGS_EQUAL(m_uefi_variable_store.variable_index.counter, 0);
+}
+
+TEST(UefiVariableStoreTests, variableIndexesWithSameData)
+{
+	psa_status_t psa_status = PSA_SUCCESS;
+	efi_status_t efi_status = EFI_SUCCESS;
+	/* Empty variable index with zero counter value */
+	uint8_t buffer[VARIABLE_INDEX_MAX_SIZE] = { 0 };
+
+	/* Set both indexes to the same data and counter value */
+	mock_store_reset(&m_persistent_store);
+
+	psa_status = m_persistent_store.backend.interface->set(
+		m_persistent_store.backend.context, OWNER_ID, DEFAULT_VARIABLE_INDEX_STORAGE_A_UID,
+		sizeof(buffer), &buffer, PSA_STORAGE_FLAG_NONE);
+	UNSIGNED_LONGLONGS_EQUAL(PSA_SUCCESS, psa_status);
+
+	psa_status = m_persistent_store.backend.interface->set(
+		m_persistent_store.backend.context, OWNER_ID, DEFAULT_VARIABLE_INDEX_STORAGE_B_UID,
+		sizeof(buffer), &buffer, PSA_STORAGE_FLAG_NONE);
+	UNSIGNED_LONGLONGS_EQUAL(PSA_SUCCESS, psa_status);
+
+	/*
+	 * Initializing the store should fail, because if there are two indexes with the same counter it cannot be decided
+	 * which has the valid data.
+	 */
+	uefi_variable_store_deinit(&m_uefi_variable_store);
+
+	efi_status = uefi_variable_store_init(&m_uefi_variable_store, OWNER_ID, MAX_VARIABLES,
+					      m_persistent_backend, m_volatile_backend);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_LOAD_ERROR, efi_status);
+}
diff --git a/components/service/uefi/smm_variable/backend/uefi_variable_store.c b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
index 5b46c13..48b81ff 100644
--- a/components/service/uefi/smm_variable/backend/uefi_variable_store.c
+++ b/components/service/uefi/smm_variable/backend/uefi_variable_store.c
@@ -19,6 +19,7 @@
 
 #include "trace.h"
 #include "util.h"
+#include <service/locator/sp/ffa/spffa_service_context.h>
 #include "variable_checker.h"
 #include "variable_index_iterator.h"
 
@@ -27,9 +28,12 @@
 #include "service/crypto/client/psa/crypto_client.h"
 #endif
 
-static void load_variable_index(struct uefi_variable_store *context);
+static psa_status_t get_active_variable_uid(struct uefi_variable_store *context,
+					    uint64_t *active_index_uid, uint32_t *counter);
 
-static efi_status_t sync_variable_index(const struct uefi_variable_store *context);
+static efi_status_t load_variable_index(struct uefi_variable_store *context);
+
+static efi_status_t sync_variable_index(struct uefi_variable_store *context);
 
 static efi_status_t check_capabilities(const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
 
@@ -42,7 +46,6 @@
 			      const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
 
 #if defined(UEFI_AUTH_VAR)
-static bool compare_guid(const EFI_GUID *guid1, const EFI_GUID *guid2);
 
 /* Creating a map of the EFI SMM variable for easier access */
 typedef struct {
@@ -75,8 +78,27 @@
 					  const efi_data_map *key_store_var,
 					  const uint8_t *hash_buffer, size_t hash_len);
 
+static bool is_private_auth_var(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
+
 static efi_status_t authenticate_variable(const struct uefi_variable_store *context,
+					  EFI_TIME *stored_timestamp,
+					  uint8_t (*fingerprint)[FINGERPRINT_SIZE],
+					  bool new_variable,
 					  SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var);
+
+static efi_status_t authenticate_secure_boot_variable(const struct uefi_variable_store *context,
+						      efi_data_map* var_map,
+						      uint8_t* hash_buffer,
+						      size_t hash_len,
+						      uint64_t max_variable_size);
+
+static efi_status_t authenticate_private_variable(const struct uefi_variable_store *context,
+						  efi_data_map* var_map,
+						  uint8_t* hash_buffer,
+						  size_t hash_len,
+						  uint64_t max_variable_size,
+						  bool new_variable,
+						  uint8_t (*fingerprint)[FINGERPRINT_SIZE]);
 #endif
 
 static efi_status_t store_variable_data(const struct uefi_variable_store *context,
@@ -116,10 +138,13 @@
 					   const uint16_t *name2, size_t size2);
 #endif
 
-/* Private UID for storing the variable index - may be overridden at build-time */
-#ifndef SMM_VARIABLE_INDEX_STORAGE_UID
-#define SMM_VARIABLE_INDEX_STORAGE_UID (1)
-#endif
+/* Private UID for storing the variable index */
+#define SMM_VARIABLE_INDEX_STORAGE_A_UID UINT64_C(0x8000000000000001)
+#define SMM_VARIABLE_INDEX_STORAGE_B_UID UINT64_C(0x8000000000000002)
+
+_Static_assert(SMM_VARIABLE_INDEX_STORAGE_A_UID != SMM_VARIABLE_INDEX_STORAGE_B_UID,
+	       "SMM_VARIABLE_INDEX_STORAGE_A_UID must not be the same value as "
+	       "SMM_VARIABLE_INDEX_STORAGE_B_UID");
 
 /* Default maximum variable size -
  * may be overridden using uefi_variable_store_set_storage_limits()
@@ -128,6 +153,10 @@
 #define DEFAULT_MAX_VARIABLE_SIZE (4096)
 #endif
 
+_Static_assert(DEFAULT_MAX_VARIABLE_SIZE <= RPC_CALLER_SESSION_SHARED_MEMORY_SIZE,
+	       "Maximum UEFI variable size must not exceed RPC buffer size. please increase " \
+	       "RPC_CALLER_SESSION_SHARED_MEMORY_SIZE or decrease DEFAULT_MAX_VARIABLE_SIZE");
+
 efi_status_t uefi_variable_store_init(struct uefi_variable_store *context, uint32_t owner_id,
 				      size_t max_variables,
 				      struct storage_backend *persistent_store,
@@ -161,12 +190,17 @@
 		if (context->index_sync_buffer_size) {
 			context->index_sync_buffer = malloc(context->index_sync_buffer_size);
 			status = (context->index_sync_buffer) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+		} else {
+			EMSG("Variable store must be capable of storing at least one variable");
+			return EFI_INVALID_PARAMETER;
 		}
 
 		/* Load the variable index with NV variable info from the persistent store */
 		if (context->index_sync_buffer) {
-			load_variable_index(context);
-			purge_orphan_index_entries(context);
+			status = load_variable_index(context);
+
+			if (status == EFI_SUCCESS)
+				purge_orphan_index_entries(context);
 		}
 	}
 
@@ -195,6 +229,8 @@
 					      const SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
 {
 	bool should_sync_index = false;
+	EFI_TIME stored_timestamp = { 0 };
+	uint8_t fingerprint[FINGERPRINT_SIZE] = { 0 };
 
 	/* Validate incoming request */
 	efi_status_t status = check_name_terminator(var->Name, var->NameSize);
@@ -223,6 +259,10 @@
 			return EFI_OUT_OF_RESOURCES;
 	}
 
+	/* Save the timestamp and fingerprints into a buffer, which can be overwritten later */
+	memcpy(&stored_timestamp, &info->metadata.timestamp, sizeof(EFI_TIME));
+	memcpy(&fingerprint, &info->metadata.fingerprint, FINGERPRINT_SIZE);
+
 	/* Control access */
 	status = check_access_permitted_on_set(context, info, var);
 
@@ -238,7 +278,9 @@
 			if (info->metadata.attributes &
 			    EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
 				status = authenticate_variable(
-					context, (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
+					context, &stored_timestamp,
+					&fingerprint, false,
+					(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
 
 				if (status != EFI_SUCCESS)
 					return status;
@@ -324,7 +366,9 @@
 			 */
 			if (var->Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) {
 				status = authenticate_variable(
-					context, (SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
+					context, &stored_timestamp,
+					&fingerprint, true,
+					(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *)var);
 
 				if (status != EFI_SUCCESS)
 					return status;
@@ -354,11 +398,14 @@
 		 * index entry.
 		 */
 		if (should_sync_index)
-			status = sync_variable_index(context);
+			status = sync_variable_index((struct uefi_variable_store *)context);
 
-		/* Store any variable data to the storage backend */
-		if (info->is_variable_set && (status == EFI_SUCCESS))
+		/* Store any variable data to the storage backend with the updated metadata */
+		if (info->is_variable_set && (status == EFI_SUCCESS)) {
+			memcpy(&info->metadata.timestamp, &stored_timestamp, sizeof(EFI_TIME));
+			memcpy(&info->metadata.fingerprint, &fingerprint, FINGERPRINT_SIZE);
 			status = store_variable_data(context, info, var);
+		}
 	}
 
 	variable_index_remove_unused_entry(&context->variable_index, info);
@@ -404,9 +451,27 @@
 efi_status_t
 uefi_variable_store_get_next_variable_name(const struct uefi_variable_store *context,
 					   SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *cur,
-					   size_t max_name_len, size_t *total_length)
+					   size_t *total_length)
 {
-	efi_status_t status = check_name_terminator(cur->Name, cur->NameSize);
+	efi_status_t status = EFI_SUCCESS;
+	size_t buffer_size = 0;
+
+	if (!cur)
+		return EFI_INVALID_PARAMETER;
+	/*
+	 * NameSize is set to the buffer size to store the names,
+	 * let's calculate the size actually being used.
+	 */
+	buffer_size = cur->NameSize;
+	for (int i = 0; i < buffer_size / sizeof(int16_t); i++) {
+		if (cur->Name[i] == 0) {
+			/* With null terminator */
+			cur->NameSize = 2*(i+1);
+			break;
+		}
+	}
+
+	status = check_name_terminator(cur->Name, cur->NameSize);
 
 	if (status != EFI_SUCCESS)
 		return status;
@@ -418,21 +483,11 @@
 			&context->variable_index, &cur->Guid, cur->NameSize, cur->Name, &status);
 
 		if (info && (status == EFI_SUCCESS)) {
-			/* The NameSize has to be set in every case according to the UEFI specs.
-			 * In case of EFI_BUFFER_TOO_SMALL it has to reflect the size of buffer
-			 * needed.
-			 */
-			cur->NameSize = info->metadata.name_size;
-			*total_length = sizeof(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME);
-
-			if (info->metadata.name_size <= max_name_len) {
+			if (info->metadata.name_size <= buffer_size) {
 				cur->Guid = info->metadata.guid;
+				cur->NameSize = info->metadata.name_size;
 				memcpy(cur->Name, info->metadata.name, info->metadata.name_size);
 
-				*total_length =
-					SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_TOTAL_SIZE(
-						cur);
-
 				/*
 				 * Check if variable is accessible (e.g boot variable is not
 				 * accessible at runtime)
@@ -442,6 +497,10 @@
 				if (status == EFI_SUCCESS)
 					break;
 			} else {
+				/* The VariableNameSize is updated to reflect the size of buffer needed */
+				cur->NameSize = info->metadata.name_size;
+				memset(cur->Name, 0, buffer_size);
+				memset(&cur->Guid, 0, sizeof(EFI_GUID));
 				status = EFI_BUFFER_TOO_SMALL;
 				break;
 			}
@@ -450,18 +509,24 @@
 			/* Do not hide original error if there is any */
 			if (status == EFI_SUCCESS)
 				status = EFI_NOT_FOUND;
+
+			memset(cur->Name, 0, buffer_size);
+			memset(&cur->Guid, 0, sizeof(EFI_GUID));
+			cur->NameSize = 0;
 			break;
 		}
 	}
 
-	/* If we found no accessible variable clear the fields for security */
-	if (status != EFI_SUCCESS) {
-		memset(cur->Name, 0, max_name_len);
-		memset(&cur->Guid, 0, sizeof(EFI_GUID));
-		if (status != EFI_BUFFER_TOO_SMALL)
-			cur->NameSize = 0;
+	if (status == EFI_SUCCESS) {
+		/* Store everything including the name */
+		*total_length =
+			SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_TOTAL_SIZE(
+				cur);
+	} else {
+		/* Do not store the name, only the size */
+		*total_length =
+			SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET;
 	}
-
 	return status;
 }
 
@@ -521,8 +586,10 @@
 	status = variable_checker_set_constraints(&constraints, info->is_constraints_set,
 						  &property->VariableProperty);
 
-	if (status == EFI_SUCCESS)
+	if (status == EFI_SUCCESS) {
 		variable_index_set_constraints(info, &constraints);
+		status = sync_variable_index(context);
+	}
 
 	variable_index_remove_unused_entry(&context->variable_index, info);
 
@@ -553,51 +620,229 @@
 	return status;
 }
 
-static void load_variable_index(struct uefi_variable_store *context)
+/* Checks which index contains the latest data, which shall be loaded */
+static psa_status_t get_active_variable_uid(struct uefi_variable_store *context,
+					    uint64_t *active_index_uid, uint32_t *counter)
+{
+	uint32_t counter_A = 0;
+	uint32_t counter_B = 0;
+	size_t data_len = 0;
+	psa_status_t psa_status_A = PSA_SUCCESS;
+	psa_status_t psa_status_B = PSA_SUCCESS;
+	struct storage_backend *persistent_store = context->persistent_store.storage_backend;
+
+	/* Set default value for the case when the index does not exist yet */
+	*active_index_uid = SMM_VARIABLE_INDEX_STORAGE_A_UID;
+	*counter = 0;
+
+	if (persistent_store) {
+		psa_status_A = persistent_store->interface->get(persistent_store->context,
+								context->owner_id,
+								SMM_VARIABLE_INDEX_STORAGE_A_UID, 0,
+								sizeof(counter_A), &counter_A,
+								&data_len);
+
+		if (psa_status_A == PSA_SUCCESS && data_len == 0) {
+			psa_status_A = persistent_store->interface->remove(
+				persistent_store->context, context->owner_id,
+				SMM_VARIABLE_INDEX_STORAGE_A_UID);
+
+			if (psa_status_A == PSA_SUCCESS)
+				psa_status_A = PSA_ERROR_DOES_NOT_EXIST;
+			else {
+				EMSG("Erronous state of variable index");
+				return PSA_ERROR_STORAGE_FAILURE;
+			}
+		}
+
+		psa_status_B = persistent_store->interface->get(persistent_store->context,
+								context->owner_id,
+								SMM_VARIABLE_INDEX_STORAGE_B_UID, 0,
+								sizeof(counter_B), &counter_B,
+								&data_len);
+
+		if (psa_status_B == PSA_SUCCESS && data_len == 0) {
+			psa_status_B = persistent_store->interface->remove(
+				persistent_store->context, context->owner_id,
+				SMM_VARIABLE_INDEX_STORAGE_B_UID);
+
+			if (psa_status_B == PSA_SUCCESS)
+				psa_status_B = PSA_ERROR_DOES_NOT_EXIST;
+			else {
+				EMSG("Erronous state of variable index");
+				return PSA_ERROR_STORAGE_FAILURE;
+			}
+		}
+
+		if ((psa_status_A != PSA_SUCCESS && psa_status_A != PSA_ERROR_DOES_NOT_EXIST) ||
+		    (psa_status_B != PSA_SUCCESS && psa_status_B != PSA_ERROR_DOES_NOT_EXIST))
+			return PSA_ERROR_STORAGE_FAILURE;
+
+		if (psa_status_A == PSA_ERROR_DOES_NOT_EXIST) {
+			if (psa_status_B == PSA_ERROR_DOES_NOT_EXIST)
+				return PSA_ERROR_DOES_NOT_EXIST;
+
+			*active_index_uid = SMM_VARIABLE_INDEX_STORAGE_B_UID;
+			*counter = counter_B;
+
+			return PSA_SUCCESS;
+		} else if (psa_status_B == PSA_ERROR_DOES_NOT_EXIST) {
+			*active_index_uid = SMM_VARIABLE_INDEX_STORAGE_A_UID;
+			*counter = counter_A;
+
+			return PSA_SUCCESS;
+		}
+
+		if (counter_A + 1 == counter_B) {
+			*active_index_uid = SMM_VARIABLE_INDEX_STORAGE_B_UID;
+			*counter = counter_B;
+			return PSA_SUCCESS;
+		} else if (counter_B + 1 == counter_A) {
+			*active_index_uid = SMM_VARIABLE_INDEX_STORAGE_A_UID;
+			*counter = counter_A;
+			return PSA_SUCCESS;
+		} else {
+			EMSG("UEFI metadata variable index is invalid.");
+			return PSA_ERROR_STORAGE_FAILURE;
+		}
+	} else {
+		EMSG("Store backend is not accessible");
+		return PSA_ERROR_STORAGE_FAILURE;
+	}
+
+	return PSA_ERROR_STORAGE_FAILURE;
+}
+
+static efi_status_t load_variable_index(struct uefi_variable_store *context)
 {
 	struct storage_backend *persistent_store = context->persistent_store.storage_backend;
+	psa_status_t psa_status = PSA_SUCCESS;
 
 	if (persistent_store) {
 		size_t data_len = 0;
+		size_t data_offset = 0;
+		struct psa_storage_info_t variable_index_info = { 0 };
 
-		psa_status_t psa_status = persistent_store->interface->get(
-			persistent_store->context, context->owner_id,
-			SMM_VARIABLE_INDEX_STORAGE_UID, 0, context->index_sync_buffer_size,
-			context->index_sync_buffer, &data_len);
+		psa_status = get_active_variable_uid(context, &context->active_variable_index_uid,
+						     &context->variable_index.counter);
+		switch (psa_status) {
+		case PSA_SUCCESS:
+			break;
 
-		if (psa_status == PSA_SUCCESS) {
-			variable_index_restore(&context->variable_index, data_len,
-					       context->index_sync_buffer);
+		case PSA_ERROR_DOES_NOT_EXIST:
+			IMSG("Variable index does not exist in NV store, continuing with empty index");
+			return EFI_SUCCESS;
+
+		default:
+			EMSG("Loading variable index failed: %d", psa_status);
+			return EFI_LOAD_ERROR;
 		}
+
+		/* Make sure the variable index fits the buffer */
+		persistent_store->interface->get_info(persistent_store->context, context->owner_id,
+						      context->active_variable_index_uid,
+						      &variable_index_info);
+
+		if (variable_index_info.size > context->index_sync_buffer_size) {
+			EMSG("Variable index cannot fit the sync buffer");
+			return EFI_LOAD_ERROR;
+		}
+
+		do {
+			psa_status = persistent_store->interface->get(
+				persistent_store->context, context->owner_id,
+				context->active_variable_index_uid, data_offset,
+				RPC_CALLER_SESSION_SHARED_MEMORY_SIZE,
+				context->index_sync_buffer + data_offset, &data_len);
+
+			if (psa_status != PSA_SUCCESS) {
+				EMSG("Loading variable index failed: %d", psa_status);
+				return EFI_LOAD_ERROR;
+			}
+
+			data_offset += data_len;
+
+		} while (data_len == RPC_CALLER_SESSION_SHARED_MEMORY_SIZE);
+
+		variable_index_restore(&context->variable_index, data_offset,
+				       context->index_sync_buffer);
+	} else {
+		EMSG("Loading variable index failed, store backend is not accessible");
+		return EFI_LOAD_ERROR;
 	}
+
+	return EFI_SUCCESS;
 }
 
-static efi_status_t sync_variable_index(const struct uefi_variable_store *context)
+static efi_status_t sync_variable_index(struct uefi_variable_store *context)
 {
 	efi_status_t status = EFI_SUCCESS;
+	psa_status_t psa_status = PSA_SUCCESS;
+	bool is_dirty = false;
 
 	/* Sync the variable index to storage if anything is dirty */
-	size_t data_len = 0;
+	size_t remaining_data_len = 0;
 
-	bool is_dirty = variable_index_dump(&context->variable_index,
-					    context->index_sync_buffer_size,
-					    context->index_sync_buffer, &data_len);
+	status = variable_index_dump(&context->variable_index, context->index_sync_buffer_size,
+				     context->index_sync_buffer, &remaining_data_len, &is_dirty);
+	if (status != EFI_SUCCESS)
+		return status;
 
 	if (is_dirty) {
 		struct storage_backend *persistent_store =
 			context->persistent_store.storage_backend;
 
 		if (persistent_store) {
-			psa_status_t psa_status = persistent_store->interface->set(
-				persistent_store->context, context->owner_id,
-				SMM_VARIABLE_INDEX_STORAGE_UID, data_len,
-				context->index_sync_buffer, PSA_STORAGE_FLAG_NONE);
+			size_t data_offset = 0;
+			uint64_t next_index_uid = 0;
 
-			status = psa_to_efi_storage_status(psa_status);
+			/* Write the older one */
+			next_index_uid = (context->active_variable_index_uid ==
+							  SMM_VARIABLE_INDEX_STORAGE_A_UID ?
+						  SMM_VARIABLE_INDEX_STORAGE_B_UID :
+						  SMM_VARIABLE_INDEX_STORAGE_A_UID);
+
+			psa_status = persistent_store->interface->remove(
+				persistent_store->context, context->owner_id, next_index_uid);
+
+			if (psa_status != PSA_SUCCESS && psa_status != PSA_ERROR_DOES_NOT_EXIST)
+				goto end;
+
+			/* Check if the index exists and create if not yet */
+			psa_status = persistent_store->interface->create(
+				persistent_store->context, context->owner_id, next_index_uid,
+				remaining_data_len, PSA_STORAGE_FLAG_NONE);
+
+			if (psa_status != PSA_SUCCESS)
+				goto end;
+
+			do {
+				size_t data_of_this_iteration = MIN(
+					remaining_data_len, RPC_CALLER_SESSION_SHARED_MEMORY_SIZE);
+
+				psa_status = persistent_store->interface->set_extended(
+					persistent_store->context, context->owner_id,
+					next_index_uid, data_offset, data_of_this_iteration,
+					context->index_sync_buffer + data_offset);
+
+				if (psa_status != PSA_SUCCESS)
+					goto end;
+
+				data_offset += RPC_CALLER_SESSION_SHARED_MEMORY_SIZE;
+				remaining_data_len -= data_of_this_iteration;
+
+			} while (remaining_data_len);
+
+			variable_index_confirm_write(&context->variable_index);
+			context->active_variable_index_uid = next_index_uid;
+		} else {
+			EMSG("Syncing variable index failed, store backend is not accessible");
+			return EFI_LOAD_ERROR;
 		}
 	}
 
-	return status;
+	end:
+	return psa_to_efi_storage_status(psa_status);
 }
 
 /* Check attribute usage rules */
@@ -693,16 +938,6 @@
 }
 
 #if defined(UEFI_AUTH_VAR)
-/*
- * Returns whether the two guid-s equal. To avoid structure padding related error
- * the fields are checked separately instead of memcmp.
- */
-static bool compare_guid(const EFI_GUID *guid1, const EFI_GUID *guid2)
-{
-	return guid1->Data1 == guid2->Data1 && guid1->Data2 == guid2->Data2 &&
-	       guid1->Data3 == guid2->Data3 &&
-	       !memcmp(&guid1->Data4, &guid2->Data4, sizeof(guid1->Data4));
-}
 
 /*
  * Creates a "map" that contains pointers to some of the fields of the SMM variable and the
@@ -985,15 +1220,6 @@
 		create_smm_variable(&(allowed_key_store_variables[1]),
 				    sizeof(EFI_KEY_EXCHANGE_KEY_NAME), maximum_variable_size,
 				    (uint8_t *)EFI_KEY_EXCHANGE_KEY_NAME, &global_variable_guid);
-	} else {
-		/*
-		 * Any other variable is considered Private Authenticated Variable.
-		 * These are verified by db
-		 */
-		create_smm_variable(&(allowed_key_store_variables[0]),
-				    sizeof(EFI_IMAGE_SECURITY_DATABASE), maximum_variable_size,
-				    (uint8_t *)EFI_IMAGE_SECURITY_DATABASE,
-				    &security_database_guid);
 	}
 
 	return EFI_SUCCESS;
@@ -1069,40 +1295,154 @@
 	return EFI_SECURITY_VIOLATION;
 }
 
-/* Basic verification of the authentication header of the new variable.
+static bool is_private_auth_var(SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
+{
+	if (compare_name_to_key_store_name(var->Name,
+					   var->NameSize, EFI_PLATFORM_KEY_NAME,
+					   sizeof(EFI_PLATFORM_KEY_NAME)) ||
+		 compare_name_to_key_store_name(
+			   var->Name, var->NameSize,
+			   EFI_KEY_EXCHANGE_KEY_NAME, sizeof(EFI_KEY_EXCHANGE_KEY_NAME)) ||
+		 compare_name_to_key_store_name(
+			 var->Name, var->NameSize,
+			 EFI_IMAGE_SECURITY_DATABASE, sizeof(EFI_IMAGE_SECURITY_DATABASE)) ||
+		 compare_name_to_key_store_name(
+			 var->Name, var->NameSize,
+			 EFI_IMAGE_SECURITY_DATABASE1, sizeof(EFI_IMAGE_SECURITY_DATABASE1)) ||
+		 compare_name_to_key_store_name(
+			 var->Name, var->NameSize,
+			 EFI_IMAGE_SECURITY_DATABASE2, sizeof(EFI_IMAGE_SECURITY_DATABASE2)) ||
+		 compare_name_to_key_store_name(
+			 var->Name, var->NameSize,
+			 EFI_IMAGE_SECURITY_DATABASE3, sizeof(EFI_IMAGE_SECURITY_DATABASE3)))
+		return false;
+
+	return true;
+}
+
+/*
+ * Basic verification of the authentication header of the new variable.
  * First finds the key variable responsible for the authentication of the new variable,
  * then verifies it.
  */
 static efi_status_t authenticate_variable(const struct uefi_variable_store *context,
+					  EFI_TIME *stored_timestamp,
+					  uint8_t (*fingerprint)[FINGERPRINT_SIZE],
+					  bool new_variable,
 					  SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *var)
 {
 	efi_status_t status = EFI_SUCCESS;
 	EFI_GUID pkcs7_guid = EFI_CERT_TYPE_PKCS7_GUID;
-	EFI_GUID global_variable_guid = EFI_GLOBAL_VARIABLE;
-	EFI_GUID security_database_guid = EFI_IMAGE_SECURITY_DATABASE_GUID;
 	SMM_VARIABLE_COMMUNICATE_QUERY_VARIABLE_INFO variable_info = { 0, 0, 0, 0 };
-	SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *pk_variable = NULL;
-	size_t pk_payload_size = 0;
 	efi_data_map var_map = { NULL, NULL, NULL, 0, 0, NULL, 0, NULL };
 	uint8_t hash_buffer[PSA_HASH_MAX_SIZE];
 	size_t hash_len = 0;
-	bool hash_result = false;
 
 	/* Create a map of the fields of the new variable including the auth header */
 	if (!init_efi_data_map(var, true, &var_map))
 		return EFI_SECURITY_VIOLATION;
 
-	/* database variables can be verified by either PK or KEK while images
-	 * should be checked by db and dbx so the length of two will be enough.
-	 */
-	SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *allowed_key_store_variables[] = { NULL, NULL };
-
 	/* Find the maximal size of variables for the GetVariable operation */
 	status = uefi_variable_store_query_variable_info(context, &variable_info);
 	if (status != EFI_SUCCESS)
 		return EFI_SECURITY_VIOLATION;
 
 	/**
+	 * UEFI: Page 246
+	 * If the EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set in a
+	 * SetVariable() call, and firmware does not support signature type of the certificate
+	 * included in the EFI_VARIABLE_AUTHENTICATION_2 descriptor, then the SetVariable() call
+	 * shall return EFI_INVALID_PARAMETER. The list of signature types supported by the
+	 * firmware is defined by the SignatureSupport variable. Signature type of the certificate
+	 * is defined by its digest and encryption algorithms.
+	 */
+	/* TODO: Should support WIN_CERT_TYPE_PKCS_SIGNED_DATA and WIN_CERT_TYPE_EFI_PKCS115 */
+	if (var_map.efi_auth_descriptor->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID)
+		return EFI_INVALID_PARAMETER;
+
+	/* Only a CertType of EFI_CERT_TYPE_PKCS7_GUID is accepted */
+	if (!compare_guid(&var_map.efi_auth_descriptor->AuthInfo.CertType, &pkcs7_guid))
+		return EFI_SECURITY_VIOLATION;
+
+	/**
+	 * Time associated with the authentication descriptor. For the TimeStamp value,
+	 * components Pad1, Nanosecond, TimeZone, Daylight and Pad2 shall be set to 0.
+	 * This means that the time shall always be expressed in GMT.
+	 *
+	 * UEFI: Page 253
+	 * 2. Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components
+	 * of the TimeStamp value are set to zero.
+	 */
+	if ((var_map.efi_auth_descriptor->TimeStamp.Pad1 != 0) ||
+	    (var_map.efi_auth_descriptor->TimeStamp.Pad2 != 0) ||
+	    (var_map.efi_auth_descriptor->TimeStamp.Nanosecond != 0) ||
+	    (var_map.efi_auth_descriptor->TimeStamp.TimeZone != 0) ||
+	    (var_map.efi_auth_descriptor->TimeStamp.Daylight != 0)) {
+		return EFI_SECURITY_VIOLATION;
+	}
+
+	/**
+	 * UEFI: Page 253
+	 * Unless the EFI_VARIABLE_APPEND_WRITE attribute is set, verify
+	 * that the TimeStamp value is later than the current
+	 * timestamp value associated with the variable
+	 */
+	if (memcmp(&var_map.efi_auth_descriptor->TimeStamp, stored_timestamp, sizeof(EFI_TIME)) > 0) {
+		/* Save new timestamp */
+		memcpy(stored_timestamp, &var_map.efi_auth_descriptor->TimeStamp, sizeof(EFI_TIME));
+	} else if (!(var->Attributes & EFI_VARIABLE_APPEND_WRITE)) {
+		EMSG("Timestamp violation");
+		return EFI_SECURITY_VIOLATION;
+	}
+
+	/* Calculate hash for the variable only once */
+	if (!calc_variable_hash(&var_map, (uint8_t *)&hash_buffer, sizeof(hash_buffer), &hash_len))
+		return EFI_SECURITY_VIOLATION;
+
+	if (is_private_auth_var(var)) {
+		/* Run Private Authenticated Variable related authentication steps */
+		status = authenticate_private_variable(context, &var_map, hash_buffer,
+						       hash_len, variable_info.MaximumVariableSize,
+						       new_variable, fingerprint);
+	} else {
+		/* Run Secure Boot related authentication steps */
+		status = authenticate_secure_boot_variable(context, &var_map, hash_buffer,
+						   hash_len, variable_info.MaximumVariableSize);
+	}
+
+	/* Remove the authentication header from the variable if the authentication is successful */
+	if (status == EFI_SUCCESS) {
+		uint8_t *smm_payload =
+			(uint8_t *)var + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(var);
+
+		memmove(smm_payload, var_map.payload, var_map.payload_len);
+		memset((uint8_t *)smm_payload + var_map.payload_len, 0,
+		       var_map.efi_auth_descriptor_len);
+
+		var->DataSize -= var_map.efi_auth_descriptor_len;
+	}
+
+	return status;
+}
+
+static efi_status_t authenticate_secure_boot_variable(const struct uefi_variable_store *context,
+						      efi_data_map* var_map,
+						      uint8_t* hash_buffer,
+						      size_t hash_len,
+						      uint64_t max_variable_size)
+{
+	efi_status_t status = EFI_SUCCESS;
+	EFI_GUID global_variable_guid = EFI_GLOBAL_VARIABLE;
+	EFI_GUID security_database_guid = EFI_IMAGE_SECURITY_DATABASE_GUID;
+	SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *pk_variable = NULL;
+	size_t pk_payload_size = 0;
+
+	/* database variables can be verified by either PK or KEK while images
+	 * should be checked by db and dbx so the length of two will be enough.
+	 */
+	SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *allowed_key_store_variables[] = { NULL, NULL };
+
+	/**
 	 * UEFI: Page 253
 	 * 3. If the variable SetupMode==1, and the variable is a secure
 	 * boot policy variable, then the firmware implementation shall
@@ -1126,20 +1466,29 @@
 	 * Platform Key is checked to enable or disable authentication.
 	 */
 	create_smm_variable(&pk_variable, sizeof(EFI_PLATFORM_KEY_NAME),
-			    variable_info.MaximumVariableSize, (uint8_t *)EFI_PLATFORM_KEY_NAME,
+			    max_variable_size, (uint8_t *)EFI_PLATFORM_KEY_NAME,
 			    &global_variable_guid);
 
 	if (!pk_variable)
 		return EFI_OUT_OF_RESOURCES;
 
 	status = uefi_variable_store_get_variable(
-		context, pk_variable, variable_info.MaximumVariableSize, &pk_payload_size);
+		context, pk_variable, max_variable_size, &pk_payload_size);
 
 	/* If PK does not exist authentication is disabled */
-	if (status != EFI_SUCCESS) {
-		free(pk_variable);
-		status = EFI_SUCCESS;
-		goto end;
+	switch (status)	{
+		case EFI_SUCCESS:
+			break;
+		case EFI_NOT_FOUND:
+			/* If PK does not exist authentication is disabled */
+			free(pk_variable);
+			status = EFI_SUCCESS;
+			goto end;
+		default:
+			EMSG("Failed to read PK");
+			free(pk_variable);
+			status = EFI_SECURITY_VIOLATION;
+			goto end;
 	}
 
 	/*
@@ -1167,53 +1516,8 @@
 		goto end;
 	}
 
-	/**
-	 * UEFI: Page 246
-	 * If the EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS attribute is set in a
-	 * SetVariable() call, and firmware does not support signature type of the certificate
-	 * included in the EFI_VARIABLE_AUTHENTICATION_2 descriptor, then the SetVariable() call
-	 * shall return EFI_INVALID_PARAMETER. The list of signature types supported by the
-	 * firmware is defined by the SignatureSupport variable. Signature type of the certificate
-	 * is defined by its digest and encryption algorithms.
-	 */
-	/* TODO: Should support WIN_CERT_TYPE_PKCS_SIGNED_DATA and WIN_CERT_TYPE_EFI_PKCS115 */
-	if (var_map.efi_auth_descriptor->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID)
-		return EFI_INVALID_PARAMETER;
-
-	/* Only a CertType of EFI_CERT_TYPE_PKCS7_GUID is accepted */
-	if (!compare_guid(&var_map.efi_auth_descriptor->AuthInfo.CertType, &pkcs7_guid))
-		return EFI_SECURITY_VIOLATION;
-
-	/**
-	 * Time associated with the authentication descriptor. For the TimeStamp value,
-	 * components Pad1, Nanosecond, TimeZone, Daylight and Pad2 shall be set to 0.
-	 * This means that the time shall always be expressed in GMT.
-	 *
-	 * UEFI: Page 253
-	 * 2. Verify that Pad1, Nanosecond, TimeZone, Daylight and Pad2 components
-	 * of the TimeStamp value are set to zero. Unless the EFI_VARIABLE_APPEND_WRITE
-	 * attribute is set, verify that the TimeStamp value is later than the current
-	 * timestamp value associated with the variable
-	 */
-	if ((var_map.efi_auth_descriptor->TimeStamp.Pad1 != 0) ||
-	    (var_map.efi_auth_descriptor->TimeStamp.Pad2 != 0) ||
-	    (var_map.efi_auth_descriptor->TimeStamp.Nanosecond != 0) ||
-	    (var_map.efi_auth_descriptor->TimeStamp.TimeZone != 0) ||
-	    (var_map.efi_auth_descriptor->TimeStamp.Daylight != 0)) {
-		return EFI_SECURITY_VIOLATION;
-	}
-
-	/* Calculate hash for the variable only once */
-	hash_result = calc_variable_hash(&var_map, (uint8_t *)&hash_buffer, sizeof(hash_buffer),
-					 &hash_len);
-
-	if (!hash_result) {
-		status = EFI_SECURITY_VIOLATION;
-		goto end;
-	}
-
-	status = select_verification_keys(var_map, global_variable_guid, security_database_guid,
-					  variable_info.MaximumVariableSize,
+	status = select_verification_keys(*var_map, global_variable_guid, security_database_guid,
+					  max_variable_size,
 					  &allowed_key_store_variables[0]);
 
 	if (status != EFI_SUCCESS)
@@ -1221,14 +1525,14 @@
 
 	for (int i = 0; i < ARRAY_SIZE(allowed_key_store_variables); i++) {
 		size_t actual_variable_length = 0; /* Unused */
-		efi_data_map allowed_key_store_var_map;
+		efi_data_map allowed_key_store_var_map = { 0 };
 
 		if (!allowed_key_store_variables[i])
 			continue;
 
 		status = uefi_variable_store_get_variable(context, allowed_key_store_variables[i],
-							  variable_info.MaximumVariableSize,
-							  &actual_variable_length);
+							max_variable_size,
+							&actual_variable_length);
 
 		if (status) {
 			/* When the parent does not exist it is considered verification failure */
@@ -1244,8 +1548,8 @@
 			goto end;
 		}
 
-		status = verify_var_by_key_var(&var_map, &allowed_key_store_var_map,
-					       (uint8_t *)&hash_buffer, hash_len);
+		status = verify_var_by_key_var(var_map, &allowed_key_store_var_map,
+					hash_buffer, hash_len);
 
 		if (status == EFI_SUCCESS)
 			goto end;
@@ -1258,19 +1562,56 @@
 			free(allowed_key_store_variables[i]);
 	}
 
-	/* Remove the authentication header from the variable if the authentication is successful */
-	if (status == EFI_SUCCESS) {
-		uint8_t *smm_payload =
-			(uint8_t *)var + SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE_DATA_OFFSET(var);
+	return status;
+}
 
-		memmove(smm_payload, var_map.payload, var_map.payload_len);
-		memset((uint8_t *)smm_payload + var_map.payload_len, 0,
-		       var_map.efi_auth_descriptor_len);
+static efi_status_t authenticate_private_variable(const struct uefi_variable_store *context,
+						  efi_data_map* var_map,
+						  uint8_t* hash_buffer,
+						  size_t hash_len,
+						  uint64_t max_variable_size,
+						  bool new_variable,
+						  uint8_t (*fingerprint)[FINGERPRINT_SIZE])
+{
+	uint8_t new_fingerprint[PSA_HASH_MAX_SIZE] = { 0 };
 
-		var->DataSize -= var_map.efi_auth_descriptor_len;
+	/* Verify the signature of the variable */
+	if (verify_pkcs7_signature(
+		var_map->efi_auth_descriptor->AuthInfo.CertData,
+		var_map->efi_auth_descriptor_certdata_len, hash_buffer,
+		hash_len, NULL, 0) != 0)
+		return EFI_SECURITY_VIOLATION;
+
+	/**
+	 * UEFI: Page 254
+	 * CN of the signing certificate’s Subject and the hash of the tbsCertificate of the
+	 * top-level issuer certificate (or the signing certificate itself if no other certificates
+	 * are present or the certificate chain is of length 1) in SignedData.certificates is
+	 * registered for use in subsequent verifications of this variable. Implementations
+	 * may store just a single hash of these two elements to reduce storage requirements.
+	 */
+	if (get_uefi_priv_auth_var_fingerprint_handler(var_map->efi_auth_descriptor->AuthInfo.CertData,
+						       var_map->efi_auth_descriptor_certdata_len,
+						       new_fingerprint)) {
+		EMSG("Failed to query variable fingerprint input");
+		return EFI_SECURITY_VIOLATION;
 	}
 
-	return status;
+	/*
+	 * The hash is SHA256 so only 32 bytes contain non zero values.
+	 * Use only that part to decrease metadata size.
+	 */
+	if (!new_variable) {
+		if (memcmp(&new_fingerprint, fingerprint, FINGERPRINT_SIZE)) {
+			EMSG("Fingerprint verification failed");
+			return EFI_SECURITY_VIOLATION;
+		}
+	} else {
+		/* Save fingerprint */
+		memcpy(fingerprint, &new_fingerprint, FINGERPRINT_SIZE);
+	}
+
+	return EFI_SUCCESS;
 }
 #endif
 
@@ -1486,7 +1827,7 @@
 	}
 
 	if (any_orphans)
-		sync_variable_index(context);
+		sync_variable_index((struct uefi_variable_store *)context);
 }
 
 static struct delegate_variable_store *
diff --git a/components/service/uefi/smm_variable/backend/uefi_variable_store.h b/components/service/uefi/smm_variable/backend/uefi_variable_store.h
index 8be5f36..9f2c4a0 100644
--- a/components/service/uefi/smm_variable/backend/uefi_variable_store.h
+++ b/components/service/uefi/smm_variable/backend/uefi_variable_store.h
@@ -52,6 +52,7 @@
 	uint32_t owner_id;
 	uint8_t *index_sync_buffer;
 	size_t index_sync_buffer_size;
+	uint64_t active_variable_index_uid;
 	struct variable_index variable_index;
 	struct delegate_variable_store persistent_store;
 	struct delegate_variable_store volatile_store;
@@ -134,8 +135,7 @@
  * Used for enumerating the store contents
  *
  * @param[in]  context uefi_variable_store instance
- * @param[out] cur Current variable name
- * @param[in]  max_name_len The maximum variable name length
+ * @param[inout] cur The size of the VariableName buffer
  * @param[out] total_len The total length of the output
  *
  * @return     EFI_SUCCESS if successful
@@ -143,7 +143,7 @@
 efi_status_t
 uefi_variable_store_get_next_variable_name(const struct uefi_variable_store *context,
 					   SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *cur,
-					   size_t max_name_len, size_t *total_length);
+					   size_t *total_length);
 
 /**
  * @brief      Query for variable info
diff --git a/components/service/uefi/smm_variable/backend/variable_index.c b/components/service/uefi/smm_variable/backend/variable_index.c
index d850dbe..9023042 100644
--- a/components/service/uefi/smm_variable/backend/variable_index.c
+++ b/components/service/uefi/smm_variable/backend/variable_index.c
@@ -10,49 +10,48 @@
 #include <stdlib.h>
 #include <string.h>
 
-/* Private functions */
-static uint64_t name_hash(const EFI_GUID *guid, size_t name_size, const int16_t *name)
-{
-	/* Using djb2 hash by Dan Bernstein */
-	uint64_t hash = 5381;
-
-	/* Calculate hash over GUID */
-	hash = ((hash << 5) + hash) + guid->Data1;
-	hash = ((hash << 5) + hash) + guid->Data2;
-	hash = ((hash << 5) + hash) + guid->Data3;
-
-	for (int i = 0; i < 8; ++i) {
-		hash = ((hash << 5) + hash) + guid->Data4[i];
-	}
-
-	/* Extend to cover name up to but not including null terminator */
-	for (size_t i = 0; i < (name_size - sizeof(int16_t)) / sizeof(int16_t); ++i) {
-		hash = ((hash << 5) + hash) + name[i];
-	}
-
-	return hash;
-}
-
 static uint64_t generate_uid(const struct variable_index *context, const EFI_GUID *guid,
 			     size_t name_size, const int16_t *name)
 {
-	uint64_t uid = name_hash(guid, name_size, name);
+	/* Find the first unsed UID in the: 1..max_variables inclusive range */
+	for (size_t candidate = 1; candidate <= context->max_variables; candidate++) {
+		for (size_t pos = 0; pos < context->max_variables; pos++) {
+			if (context->entries[pos].in_use &&
+			    context->entries[pos].info.metadata.uid == candidate) {
+				// The candidate UID is already being used
+				goto skip;
+			}
+		}
 
-	/* todo - handle collision  */
-	(void)context;
+		return candidate;
 
-	return uid;
+skip:
+	}
+
+	return 0;
+}
+
+static bool is_matching_entry(const EFI_GUID *guid, const int16_t *name, size_t name_size,
+			      const struct variable_metadata *metadata)
+{
+	if (!compare_guid(guid, &metadata->guid))
+		return false;
+
+	if (name_size != metadata->name_size)
+		return false;
+
+	return (memcmp(name, metadata->name, name_size) == 0);
 }
 
 static int find_variable(const struct variable_index *context, const EFI_GUID *guid,
 			 size_t name_size, const int16_t *name)
 {
 	int found_pos = -1;
-	uint64_t uid = name_hash(guid, name_size, name);
 
 	for (size_t pos = 0; pos < context->max_variables; pos++) {
 		if ((context->entries[pos].in_use) &&
-		    (uid == context->entries[pos].info.metadata.uid)) {
+		    is_matching_entry(guid, name, name_size,
+				      &context->entries[pos].info.metadata)) {
 			found_pos = pos;
 			break;
 		}
@@ -92,6 +91,7 @@
 efi_status_t variable_index_init(struct variable_index *context, size_t max_variables)
 {
 	context->max_variables = max_variables;
+	context->counter = 0;
 	context->entries =
 		(struct variable_entry *)malloc(sizeof(struct variable_entry) * max_variables);
 
@@ -109,7 +109,9 @@
 
 size_t variable_index_max_dump_size(struct variable_index *context)
 {
-	return sizeof(struct variable_metadata) * context->max_variables;
+	return sizeof(context->counter) + (sizeof(struct variable_metadata) + sizeof(bool) +
+					   sizeof(struct variable_constraints)) *
+						  context->max_variables;
 }
 
 struct variable_info *variable_index_find(const struct variable_index *context,
@@ -194,7 +196,12 @@
 
 			/* Initialize metadata */
 			info->metadata.uid = generate_uid(context, guid, name_size, name);
+			if (!info->metadata.uid)
+				return NULL;
+
 			info->metadata.guid = *guid;
+			memset(&info->metadata.timestamp, 0, sizeof(EFI_TIME));
+			memset(&info->metadata.fingerprint, 0, FINGERPRINT_SIZE);
 			info->metadata.attributes = 0;
 			info->metadata.name_size = name_size;
 			memcpy(info->metadata.name, name, name_size);
@@ -263,64 +270,143 @@
 				    const struct variable_constraints *constraints)
 {
 	if (info) {
+		struct variable_entry *entry = containing_entry(info);
+
 		info->check_constraints = *constraints;
 		info->is_constraints_set = true;
+
+		mark_dirty(entry);
 	}
 }
 
-bool variable_index_dump(const struct variable_index *context, size_t buffer_size, uint8_t *buffer,
-			 size_t *data_len)
+efi_status_t variable_index_dump(const struct variable_index *context, size_t buffer_size,
+				 uint8_t *buffer, size_t *data_len, bool *any_dirty)
 {
-	bool any_dirty = false;
 	uint8_t *dump_pos = buffer;
 	size_t bytes_dumped = 0;
 
+	*data_len = 0;
+	*any_dirty = false;
+
+	/*
+	 * Intentionally letting the counter overflow.
+	 * The buffer (index_sync_buffer) is provided by malloc, which allocates memory to a boundary
+	 * suitable for any default data type of the system (e.g uint32_t)
+	 */
+	*((uint32_t *)dump_pos) = context->counter + 1;
+	bytes_dumped += sizeof(context->counter);
+	dump_pos += sizeof(context->counter);
+
+	/* Store variables */
 	for (size_t pos = 0; pos < context->max_variables; pos++) {
 		struct variable_entry *entry = &context->entries[pos];
 		struct variable_metadata *metadata = &entry->info.metadata;
+		struct variable_constraints *constraints = &entry->info.check_constraints;
 
 		if (entry->in_use && entry->info.is_variable_set &&
-		    (metadata->attributes & EFI_VARIABLE_NON_VOLATILE) &&
-		    ((bytes_dumped + sizeof(struct variable_metadata)) <= buffer_size)) {
+		    (metadata->attributes & EFI_VARIABLE_NON_VOLATILE)) {
+			/* Store metadata */
+			if (bytes_dumped + sizeof(struct variable_metadata) > buffer_size)
+				return EFI_BUFFER_TOO_SMALL;
+
 			memcpy(dump_pos, metadata, sizeof(struct variable_metadata));
 			bytes_dumped += sizeof(struct variable_metadata);
 			dump_pos += sizeof(struct variable_metadata);
+
+			/* Store constraints' status */
+			if (bytes_dumped + sizeof(entry->info.is_constraints_set) > buffer_size)
+				return EFI_BUFFER_TOO_SMALL;
+
+			memcpy(dump_pos, &entry->info.is_constraints_set,
+			       sizeof(entry->info.is_constraints_set));
+			bytes_dumped += sizeof(entry->info.is_constraints_set);
+			dump_pos += sizeof(entry->info.is_constraints_set);
+
+			/* Store constraints, if they are set */
+			if (entry->info.is_constraints_set) {
+				if (bytes_dumped + sizeof(entry->info.check_constraints) >
+				    buffer_size)
+					return EFI_BUFFER_TOO_SMALL;
+
+				memcpy(dump_pos, constraints,
+				       sizeof(entry->info.check_constraints));
+				bytes_dumped += sizeof(entry->info.check_constraints);
+				dump_pos += sizeof(entry->info.check_constraints);
+			}
 		}
 
-		any_dirty |= entry->dirty;
+		*any_dirty |= entry->dirty;
 		entry->dirty = false;
 	}
 
 	*data_len = bytes_dumped;
 
-	return any_dirty;
+	return EFI_SUCCESS;
 }
 
-size_t variable_index_restore(const struct variable_index *context, size_t data_len,
+void variable_index_confirm_write(struct variable_index *context)
+{
+	context->counter++;
+}
+
+size_t variable_index_restore(struct variable_index *context, size_t data_len,
 			      const uint8_t *buffer)
 {
 	size_t bytes_loaded = 0;
 	const uint8_t *load_pos = buffer;
 	int pos = 0;
 
+	if (data_len >= sizeof(context->counter)) {
+		context->counter = *((uint32_t *)load_pos);
+		bytes_loaded += sizeof(context->counter);
+		load_pos += sizeof(context->counter);
+	}
+
 	while (bytes_loaded < data_len) {
+		struct variable_entry *entry = &context->entries[pos];
+
 		if ((data_len - bytes_loaded) >= sizeof(struct variable_metadata)) {
-			struct variable_entry *entry = &context->entries[pos];
 			struct variable_metadata *metadata = &entry->info.metadata;
 
+			/* Load metadata */
 			memcpy(metadata, load_pos, sizeof(struct variable_metadata));
-
-			entry->info.is_variable_set = true;
-			entry->in_use = true;
-
 			bytes_loaded += sizeof(struct variable_metadata);
 			load_pos += sizeof(struct variable_metadata);
-
-			++pos;
 		} else {
 			/* Not a whole number of variable_metadata structs! */
 			break;
 		}
+
+		if ((data_len - bytes_loaded) >= sizeof(entry->info.is_constraints_set)) {
+			/* Load constraints' status */
+			memcpy(&entry->info.is_constraints_set, load_pos,
+			       sizeof(entry->info.is_constraints_set));
+			bytes_loaded += sizeof(entry->info.is_constraints_set);
+			load_pos += sizeof(entry->info.is_constraints_set);
+		} else {
+			/* Not enough space for constraints' status! */
+			break;
+		}
+
+		if (entry->info.is_constraints_set) {
+			if ((data_len - bytes_loaded) >= sizeof(struct variable_constraints)) {
+				struct variable_constraints *constraints =
+					&entry->info.check_constraints;
+
+				/* Load constraints if they are set */
+				memcpy(constraints, load_pos, sizeof(struct variable_constraints));
+				bytes_loaded += sizeof(struct variable_constraints);
+				load_pos += sizeof(struct variable_constraints);
+			} else {
+				/* Not a whole number of variable_constraints structs! */
+				break;
+			}
+		}
+
+		entry->info.is_variable_set = true;
+		entry->in_use = true;
+
+		++pos;
 	}
 
 	return bytes_loaded;
diff --git a/components/service/uefi/smm_variable/backend/variable_index.h b/components/service/uefi/smm_variable/backend/variable_index.h
index 5d3b7a7..592dddc 100644
--- a/components/service/uefi/smm_variable/backend/variable_index.h
+++ b/components/service/uefi/smm_variable/backend/variable_index.h
@@ -9,6 +9,7 @@
 #define VARIABLE_INDEX_H
 
 #include <protocols/common/efi/efi_status.h>
+#include <protocols/common/efi/efi_types.h>
 #include <protocols/service/smm_variable/smm_variable_proto.h>
 #include <stdbool.h>
 #include <stddef.h>
@@ -24,6 +25,7 @@
  * Implementation limits
  */
 #define VARIABLE_INDEX_MAX_NAME_SIZE (64)
+#define FINGERPRINT_SIZE             (32)
 
 /**
  * \brief variable_metadata structure definition
@@ -32,6 +34,8 @@
  */
 struct variable_metadata {
 	EFI_GUID guid;
+	EFI_TIME timestamp;
+	uint8_t fingerprint[FINGERPRINT_SIZE];
 	size_t name_size;
 	int16_t name[VARIABLE_INDEX_MAX_NAME_SIZE];
 	uint32_t attributes;
@@ -71,6 +75,7 @@
  */
 struct variable_index {
 	size_t max_variables;
+	uint32_t counter;
 	struct variable_entry *entries;
 };
 
@@ -197,11 +202,20 @@
  * @param[in]  buffer_size Size of destination buffer
  * @param[in]  buffer Dump to this buffer
  * @param[out] data_len Length of serialized data
+ * @param[out] any_dirty True if there is unsaved data
  *
- * @return     True if there is unsaved data
+ * @return     EFI_SUCCESS if all the changes are dumped successfully
  */
-bool variable_index_dump(const struct variable_index *context, size_t buffer_size, uint8_t *buffer,
-			 size_t *data_len);
+efi_status_t variable_index_dump(const struct variable_index *context, size_t buffer_size,
+				 uint8_t *buffer, size_t *data_len, bool *any_dirty);
+
+/**
+ * @brief     Confirms the successful write of the variable index into the storage
+ *            by stepping the counter.
+ *
+ * @param[in] context variable_index
+ */
+void variable_index_confirm_write(struct variable_index *context);
 
 /**
  * @brief      Restore the serialized index contents
@@ -215,7 +229,7 @@
  *
  * @return     Number of bytes loaded
  */
-size_t variable_index_restore(const struct variable_index *context, size_t data_len,
+size_t variable_index_restore(struct variable_index *context, size_t data_len,
 			      const uint8_t *buffer);
 
 #ifdef __cplusplus
diff --git a/components/service/uefi/smm_variable/client/cpp/smm_variable_client.cpp b/components/service/uefi/smm_variable/client/cpp/smm_variable_client.cpp
index f71d0c8..d394489 100644
--- a/components/service/uefi/smm_variable/client/cpp/smm_variable_client.cpp
+++ b/components/service/uefi/smm_variable/client/cpp/smm_variable_client.cpp
@@ -166,7 +166,6 @@
 
 	if (call_handle) {
 		uint8_t *resp_buf;
-		size_t resp_len;
 		service_status_t service_status;
 
 		SMM_VARIABLE_COMMUNICATE_ACCESS_VARIABLE *access_var =
diff --git a/components/service/uefi/smm_variable/frontend/mm_communicate/tests.cmake b/components/service/uefi/smm_variable/frontend/mm_communicate/tests.cmake
index 50b0b9a..7d8b7cd 100644
--- a/components/service/uefi/smm_variable/frontend/mm_communicate/tests.cmake
+++ b/components/service/uefi/smm_variable/frontend/mm_communicate/tests.cmake
@@ -22,4 +22,5 @@
 		${UNIT_TEST_PROJECT_PATH}/components/rpc/common/interface
 	COMPILE_DEFINITIONS
 		-DARM64
+		-DCFG_FFA_VERSION=0x00010001
 )
diff --git a/components/service/uefi/smm_variable/provider/smm_variable_provider.c b/components/service/uefi/smm_variable/provider/smm_variable_provider.c
index 1875397..1a52693 100644
--- a/components/service/uefi/smm_variable/provider/smm_variable_provider.c
+++ b/components/service/uefi/smm_variable/provider/smm_variable_provider.c
@@ -81,30 +81,6 @@
 	return efi_status;
 }
 
-static efi_status_t sanitize_get_next_var_name_param(struct rpc_request *req, size_t *param_len)
-{
-	efi_status_t efi_status = EFI_INVALID_PARAMETER;
-	*param_len = 0;
-	const struct rpc_buffer *req_buf = &req->request;
-
-	if (req_buf->data_length >= SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET) {
-		const SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *param =
-			(const SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *)req_buf->data;
-
-		size_t max_space_for_name =
-			req_buf->data_length -
-			SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET;
-
-		if (param->NameSize <= max_space_for_name) {
-			*param_len =
-				SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_TOTAL_SIZE(param);
-			efi_status = EFI_SUCCESS;
-		}
-	}
-
-	return efi_status;
-}
-
 static efi_status_t sanitize_var_check_property_param(struct rpc_request *req, size_t *param_len)
 {
 	efi_status_t efi_status = EFI_INVALID_PARAMETER;
@@ -146,7 +122,7 @@
 			struct rpc_buffer *req_buf = &req->request;
 			size_t max_data_len = resp_buf->size - param_len;
 
-			memmove(resp_buf->data, req_buf->data, param_len);
+			memcpy(resp_buf->data, req_buf->data, param_len);
 
 			efi_status = uefi_variable_store_get_variable(
 				&this_instance->variable_store,
@@ -167,30 +143,21 @@
 {
 	struct smm_variable_provider *this_instance = (struct smm_variable_provider *)context;
 
-	size_t param_len = 0;
-	efi_status_t efi_status = sanitize_get_next_var_name_param(req, &param_len);
+	efi_status_t efi_status = EFI_SUCCESS;
+	size_t variable_size = 0;
 
-	if (efi_status == EFI_SUCCESS) {
-		/* Valid get next variable name header */
-		struct rpc_buffer *resp_buf = &req->response;
+	/* Valid get next variable name header */
+	struct rpc_buffer *resp_buf = &req->response;
+	struct rpc_buffer *req_buf = &req->request;
 
-		if (resp_buf->size >= param_len) {
-			struct rpc_buffer *req_buf = &req->request;
-			size_t max_name_len =
-				resp_buf->size -
-				SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME_NAME_OFFSET;
+	memcpy(resp_buf->data, req_buf->data, req_buf->data_length);
 
-			memmove(resp_buf->data, req_buf->data, param_len);
+	efi_status = uefi_variable_store_get_next_variable_name(
+		&this_instance->variable_store,
+		(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *)resp_buf->data,
+		&variable_size);
 
-			efi_status = uefi_variable_store_get_next_variable_name(
-				&this_instance->variable_store,
-				(SMM_VARIABLE_COMMUNICATE_GET_NEXT_VARIABLE_NAME *)resp_buf->data,
-				max_name_len, &resp_buf->data_length);
-		} else {
-			/* Reponse buffer not big enough */
-			efi_status = EFI_BAD_BUFFER_SIZE;
-		}
-	}
+	resp_buf->data_length = variable_size;
 
 	req->service_status = efi_status;
 
@@ -242,7 +209,7 @@
 		struct rpc_buffer *resp_buf = &req->response;
 
 		if (resp_buf->size >= req_buf->data_length) {
-			memmove(resp_buf->data, req_buf->data, req_buf->data_length);
+			memcpy(resp_buf->data, req_buf->data, req_buf->data_length);
 
 			efi_status = uefi_variable_store_query_variable_info(
 				&this_instance->variable_store,
@@ -310,7 +277,7 @@
 
 		if (resp_buf->size >= param_len) {
 			struct rpc_buffer *req_buf = &req->request;
-			memmove(resp_buf->data, req_buf->data, param_len);
+			memcpy(resp_buf->data, req_buf->data, param_len);
 			resp_buf->data_length = param_len;
 
 			efi_status = uefi_variable_store_get_var_check_property(
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/KEK.h b/components/service/uefi/smm_variable/test/service/auth_vectors/KEK.h
index 9b28ed3..82bed52 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/KEK.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/KEK.h
@@ -7,245 +7,243 @@
  */
 
 unsigned char KEK_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0,
-  0x7a, 0xa6, 0xe6, 0x9b, 0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b,
-  0xc7, 0xa8, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x52, 0xe9, 0x66, 0x81, 0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82,
+  0x66, 0xd8, 0x3d, 0x2b, 0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xcb, 0x94, 0x4f, 0x33, 0x47, 0xe3, 0xb3,
-  0xd0, 0x34, 0x45, 0x48, 0xea, 0x6c, 0x66, 0x8d, 0xb0, 0x97, 0x41, 0xe8,
-  0x81, 0x7f, 0xab, 0x83, 0xa5, 0x9f, 0xa6, 0x5d, 0x47, 0x9b, 0x60, 0x55,
-  0xc3, 0x70, 0x2c, 0xf5, 0x96, 0x9f, 0xa8, 0xdb, 0xc0, 0xca, 0x63, 0x7c,
-  0x34, 0xed, 0x14, 0x9e, 0xc0, 0xbe, 0xab, 0xe4, 0x3b, 0x73, 0xed, 0x62,
-  0x24, 0xe8, 0x68, 0xa4, 0x14, 0x10, 0x50, 0x8f, 0x7f, 0x59, 0xad, 0xec,
-  0x16, 0x60, 0xfe, 0x1f, 0x60, 0x3b, 0x9a, 0x7b, 0x7a, 0xc3, 0x3e, 0xf4,
-  0xcf, 0x39, 0x27, 0x70, 0xb9, 0xd9, 0x0a, 0x40, 0xc7, 0x7f, 0x41, 0x80,
-  0xd3, 0xe0, 0x22, 0x15, 0x1a, 0x91, 0x0e, 0x4a, 0xa7, 0x52, 0x33, 0x72,
-  0xf2, 0x46, 0x03, 0x42, 0x36, 0x85, 0x27, 0xf0, 0x2f, 0x9f, 0x56, 0xa4,
-  0xd5, 0xdc, 0x00, 0xd5, 0x5e, 0xe5, 0x1a, 0x08, 0xae, 0xdc, 0x80, 0xb9,
-  0xa4, 0xcf, 0x58, 0xf1, 0xd4, 0x38, 0x5f, 0xe1, 0xff, 0x81, 0x01, 0xff,
-  0x17, 0x77, 0xe7, 0x4b, 0xee, 0x91, 0xaf, 0x3a, 0xf9, 0x73, 0xd9, 0x6f,
-  0xe9, 0x22, 0x55, 0x15, 0x17, 0xa9, 0xc9, 0xde, 0xfc, 0x63, 0xfc, 0x84,
-  0x96, 0xb7, 0xf8, 0x40, 0x63, 0x5f, 0x2c, 0x21, 0x20, 0x1e, 0x37, 0x14,
-  0x1b, 0x4e, 0x76, 0xec, 0x3a, 0xcb, 0xd5, 0xdc, 0xef, 0x96, 0x37, 0x43,
-  0x46, 0x4c, 0x2e, 0xf4, 0xcb, 0x58, 0x90, 0x91, 0x35, 0x6d, 0xb5, 0x58,
-  0xb8, 0xb7, 0x74, 0x72, 0x80, 0x3f, 0xb7, 0xd0, 0x1b, 0xca, 0x47, 0x18,
-  0xc9, 0x99, 0x4d, 0x74, 0x97, 0x57, 0xc4, 0x2f, 0x2e, 0x2a, 0xd0, 0x95,
-  0xc2, 0x1e, 0x64, 0x8d, 0xbd, 0xd1, 0x7e, 0xf6, 0x6c, 0x44, 0x01, 0x1f,
-  0x37, 0xc0, 0x67, 0x7a, 0x78, 0x47, 0x21, 0xb4, 0x0d, 0xc6, 0xab, 0x81,
-  0x7e, 0x1c, 0x10, 0x5d, 0x01, 0x2e, 0xfe, 0x41, 0x93, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4,
-  0xbb, 0x06, 0xa7, 0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66,
-  0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4, 0xbb, 0x06, 0xa7,
-  0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66, 0x08, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3a,
-  0xae, 0xa0, 0xfa, 0x34, 0x4a, 0x52, 0x24, 0x90, 0x3a, 0xba, 0x33, 0x61,
-  0x0f, 0xc8, 0x6f, 0xbc, 0x72, 0xf8, 0xc3, 0x98, 0x04, 0xe1, 0xcb, 0xf2,
-  0x82, 0xfd, 0x83, 0x59, 0x51, 0x23, 0x71, 0xf4, 0xce, 0xe9, 0x36, 0x4d,
-  0x0a, 0xd3, 0x11, 0x6d, 0x51, 0xb7, 0xd1, 0x9f, 0x9b, 0x85, 0x5c, 0x25,
-  0x11, 0x9c, 0x13, 0xf6, 0x33, 0xd8, 0xa4, 0x27, 0xef, 0x90, 0x56, 0x21,
-  0xe3, 0x90, 0x10, 0x2b, 0x50, 0x46, 0x6e, 0x8a, 0x84, 0x3e, 0x30, 0x4c,
-  0xc2, 0xdf, 0x81, 0x60, 0xdf, 0xb8, 0x06, 0xd8, 0x2f, 0xcf, 0x3f, 0xb8,
-  0xbe, 0x04, 0xa4, 0xbb, 0xba, 0x65, 0x9f, 0x4e, 0xc4, 0x05, 0xbe, 0x9e,
-  0xfe, 0xa9, 0x0c, 0x06, 0x81, 0xcc, 0xa4, 0x66, 0xb0, 0x14, 0x48, 0xc9,
-  0x24, 0x88, 0xd8, 0xdc, 0xf2, 0x5c, 0xb5, 0x59, 0x66, 0x4f, 0xc6, 0xa4,
-  0xa3, 0x96, 0xa8, 0x48, 0x3b, 0x43, 0xff, 0xe0, 0x10, 0x53, 0x79, 0x47,
-  0x74, 0xe8, 0xbc, 0xa9, 0x4f, 0x8e, 0x1f, 0xfb, 0xf8, 0xad, 0x8d, 0x10,
-  0x80, 0x8f, 0x80, 0xf8, 0x5b, 0x36, 0xff, 0x60, 0x0b, 0x3f, 0xb2, 0x2f,
-  0x46, 0x27, 0x43, 0x00, 0x1a, 0x0d, 0xb8, 0x91, 0x4e, 0x84, 0xb1, 0x94,
-  0xc2, 0xca, 0xd6, 0x36, 0x4d, 0xc6, 0xda, 0x53, 0x71, 0xcc, 0xc8, 0x8e,
-  0x9c, 0xdb, 0x31, 0xbb, 0x93, 0x49, 0xa7, 0xf4, 0x0b, 0x19, 0xcb, 0xaa,
-  0x2b, 0x0c, 0xf4, 0xc7, 0x59, 0x8a, 0xc6, 0x59, 0x0b, 0x1d, 0x2f, 0xc3,
-  0xcf, 0x06, 0xcf, 0x2e, 0x6b, 0x15, 0x6f, 0xba, 0xd1, 0xfa, 0x7d, 0x7f,
-  0xaa, 0x99, 0x09, 0x63, 0xa8, 0xdd, 0x6c, 0xdb, 0x6a, 0x5e, 0x00, 0x5e,
-  0x89, 0x11, 0xe3, 0xbd, 0xf6, 0xcb, 0x13, 0x89, 0x6a, 0xb8, 0x7e, 0x89,
-  0xbc, 0xa5, 0xec, 0x68, 0x85, 0xf0, 0xaa, 0x05, 0x91, 0xc1, 0x79, 0xa1,
-  0x1c, 0x9d, 0x32, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x33, 0x39,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x33, 0x39, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
   0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x31, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0, 0x7a, 0xa6, 0xe6, 0x9b,
-  0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b, 0xc7, 0xa8, 0x37, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x83, 0x75, 0x52,
-  0xe9, 0x31, 0x81, 0x65, 0x22, 0x9d, 0x8e, 0x5f, 0xeb, 0x86, 0x0a, 0x0c,
-  0x10, 0x1f, 0xe2, 0x2e, 0xed, 0x1a, 0x88, 0x02, 0xfc, 0xd8, 0x50, 0xaa,
-  0xa8, 0xdd, 0x1f, 0xfd, 0x25, 0xac, 0xd8, 0x2d, 0xe1, 0x06, 0x4e, 0x1a,
-  0xad, 0xbe, 0x00, 0xe1, 0x59, 0x23, 0x92, 0x78, 0xf2, 0x31, 0x62, 0x67,
-  0xa6, 0x3a, 0x0a, 0x04, 0x21, 0xb2, 0xeb, 0x72, 0x99, 0xab, 0xad, 0xdb,
-  0xee, 0x2f, 0x21, 0x6a, 0x71, 0xfe, 0x67, 0x89, 0x3d, 0xf5, 0xce, 0x4b,
-  0x89, 0x79, 0x07, 0x3a, 0xfd, 0xc3, 0xb2, 0x39, 0x2c, 0xec, 0x4f, 0x96,
-  0xcc, 0xc9, 0xd3, 0xd9, 0x9c, 0x92, 0x1a, 0xbe, 0x37, 0xd2, 0xc7, 0x4b,
-  0x61, 0xbd, 0x95, 0x0a, 0x0a, 0x9b, 0xb9, 0x10, 0xce, 0x7a, 0x38, 0x28,
-  0x92, 0xbb, 0x2c, 0xc6, 0x9d, 0xf7, 0x3b, 0xec, 0xd5, 0x3b, 0xd9, 0x1b,
-  0xbb, 0x15, 0x09, 0x55, 0x3f, 0x38, 0x05, 0x6b, 0x3c, 0xf4, 0x9c, 0xb5,
-  0x50, 0xf0, 0x50, 0x09, 0xf1, 0x0a, 0xd4, 0x19, 0x10, 0xb6, 0x32, 0x68,
-  0xf0, 0x51, 0xd8, 0x18, 0x4d, 0xe3, 0x99, 0x11, 0x89, 0x42, 0x1b, 0xe5,
-  0x89, 0x86, 0x09, 0x58, 0x69, 0x31, 0x1d, 0x06, 0xc0, 0xa4, 0x38, 0x3a,
-  0x96, 0x71, 0xab, 0xd9, 0xe3, 0x61, 0xb9, 0x9c, 0x40, 0x4d, 0x9c, 0x20,
-  0x25, 0x55, 0xc3, 0x52, 0xd8, 0x03, 0x17, 0xf7, 0x9f, 0x7a, 0x2b, 0xa4,
-  0xb7, 0xa7, 0x85, 0x53, 0x2a, 0x93, 0x28, 0x23, 0xa0, 0xf3, 0x18, 0xee,
-  0x9e, 0x38, 0x90, 0x07, 0xbb, 0x70, 0x29, 0xab, 0x35, 0x8b, 0xc5, 0x45,
-  0x00, 0xd8, 0xd8, 0x25, 0x56, 0x41, 0xbb, 0xe2, 0x0f, 0x3b, 0xd1, 0xfb,
-  0x36, 0xd3, 0x9c, 0x6c, 0xf1, 0x8a, 0x31, 0x20, 0x93, 0xb4, 0xa6, 0x4f,
-  0x15, 0xe7, 0xcd, 0xfa, 0xc6, 0x2e, 0x1d, 0x2f, 0xe5, 0x91, 0x7e, 0x66,
-  0xe5, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab,
+  0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb4, 0xbd,
+  0xd5, 0x2a, 0xdb, 0x3a, 0x4d, 0x37, 0x36, 0x4d, 0xbd, 0x2d, 0xdd, 0x31,
+  0xa0, 0x7c, 0x7b, 0x7e, 0xe9, 0x55, 0x50, 0x4b, 0xe5, 0x61, 0x69, 0x6e,
+  0x08, 0xe2, 0x82, 0x54, 0xfb, 0x00, 0xb6, 0x47, 0x01, 0x5c, 0x5b, 0x73,
+  0xa3, 0xde, 0x30, 0xa7, 0xd9, 0x8c, 0xeb, 0x4f, 0xda, 0x0a, 0x94, 0xc1,
+  0xd3, 0x97, 0x5c, 0xa7, 0x6f, 0x9e, 0xaa, 0xec, 0xa4, 0xf6, 0x8e, 0x73,
+  0x60, 0xe3, 0xac, 0xf7, 0x7e, 0x9b, 0x08, 0x30, 0x52, 0xff, 0x95, 0xb3,
+  0x7f, 0xf6, 0x6d, 0x5f, 0xa3, 0xcd, 0xa6, 0x56, 0x71, 0x33, 0xd0, 0xb4,
+  0xff, 0x03, 0x8c, 0xb2, 0x32, 0x91, 0x48, 0x85, 0x24, 0xd0, 0x68, 0x4c,
+  0xce, 0x62, 0xea, 0xca, 0xad, 0xa7, 0x72, 0x35, 0x14, 0xc3, 0x1d, 0x0a,
+  0x36, 0xb0, 0xd4, 0xcb, 0xd8, 0x0c, 0x98, 0xb9, 0x5f, 0x9b, 0xaa, 0x68,
+  0x27, 0xfc, 0xe2, 0xa0, 0x36, 0xee, 0xbc, 0x64, 0xfe, 0x8c, 0x50, 0xff,
+  0xb1, 0x4b, 0x68, 0xcb, 0x94, 0x38, 0x30, 0x9d, 0x67, 0x62, 0x55, 0x1e,
+  0x63, 0x79, 0x1b, 0xad, 0xd2, 0x5e, 0xb6, 0x5f, 0xb2, 0xc5, 0x0d, 0x9d,
+  0x4d, 0xc8, 0xa4, 0xfc, 0x83, 0x5e, 0x18, 0xee, 0xd1, 0xd7, 0x76, 0xe4,
+  0xb0, 0x2b, 0xd0, 0x2c, 0x17, 0xc9, 0x90, 0xe8, 0x80, 0x55, 0x57, 0xbb,
+  0x0a, 0x46, 0x21, 0x7e, 0x3b, 0x14, 0x77, 0xf0, 0xd8, 0x0c, 0x16, 0x37,
+  0x83, 0x8e, 0x1f, 0x4f, 0xaa, 0x00, 0x5c, 0x5d, 0x47, 0xd4, 0xcf, 0x73,
+  0x86, 0x3c, 0x58, 0x87, 0x82, 0xb1, 0x1d, 0x23, 0xac, 0x24, 0x76, 0xc8,
+  0xcb, 0xca, 0x4f, 0xd6, 0xf0, 0x8f, 0xcd, 0xa9, 0x63, 0xce, 0x57, 0x71,
+  0x88, 0xba, 0x20, 0x04, 0x94, 0x83, 0x87, 0x97, 0xc7, 0xd1, 0xdf, 0xc1,
+  0x1c, 0x07, 0x3f, 0x08, 0x53, 0x11, 0x9a, 0x07, 0x9f, 0xd9, 0x37, 0x96,
+  0x57, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x09, 0x75,
+  0x54, 0x4c, 0x71, 0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87,
+  0xe2, 0x96, 0xcb, 0x57, 0x99, 0xc4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x09, 0x75, 0x54, 0x4c, 0x71,
+  0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87, 0xe2, 0x96, 0xcb,
+  0x57, 0x99, 0xc4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x18, 0x8f, 0x0f, 0xbb, 0x2b, 0x58, 0xe1, 0x96,
+  0x9c, 0xd2, 0x9d, 0x38, 0x1e, 0x10, 0x1f, 0x98, 0x21, 0xb3, 0x13, 0x49,
+  0x47, 0x09, 0xd5, 0x4c, 0x97, 0x8f, 0xbb, 0x18, 0xd7, 0xe2, 0x8c, 0x0d,
+  0x67, 0x23, 0xf3, 0x3b, 0xfc, 0x7f, 0x7a, 0x42, 0xb5, 0x7d, 0xb4, 0x32,
+  0x10, 0xd4, 0xae, 0x42, 0x7f, 0xb8, 0x61, 0xbe, 0x82, 0x84, 0x7e, 0xa2,
+  0xed, 0xca, 0xd0, 0x0e, 0x1e, 0xa7, 0x6f, 0x74, 0xb3, 0xe7, 0xbe, 0x8e,
+  0xbd, 0x8d, 0x55, 0xcd, 0x4a, 0x3f, 0x2b, 0x14, 0x7c, 0xe4, 0x12, 0xf6,
+  0xb5, 0xcf, 0x80, 0xa5, 0xbc, 0x06, 0x27, 0xcd, 0xa1, 0x99, 0x90, 0x06,
+  0x16, 0x8f, 0x66, 0xe4, 0x2e, 0xb2, 0x5a, 0x00, 0xaf, 0xe5, 0x72, 0x4a,
+  0x7a, 0x7d, 0x81, 0xa5, 0x85, 0xe1, 0x65, 0x9f, 0xa0, 0xf8, 0x96, 0xda,
+  0x92, 0xbf, 0xa3, 0xce, 0xc6, 0xfc, 0x98, 0x0c, 0xe8, 0x54, 0x1a, 0x38,
+  0xd7, 0x6e, 0x95, 0x7d, 0x04, 0xe9, 0xc3, 0x26, 0x89, 0xfb, 0x3a, 0xe0,
+  0x2e, 0xae, 0x6a, 0xfe, 0xec, 0x6f, 0xe2, 0x6a, 0xcf, 0x6e, 0x67, 0x52,
+  0x3b, 0xb7, 0x11, 0xb4, 0x68, 0x77, 0xb5, 0x99, 0xe5, 0x01, 0x68, 0xbb,
+  0x94, 0xe2, 0x00, 0x12, 0x86, 0x92, 0x27, 0xa0, 0x8b, 0xbe, 0x1d, 0x62,
+  0xce, 0x7a, 0x1e, 0x6a, 0xa7, 0xfe, 0x28, 0x20, 0xfc, 0xd6, 0x99, 0xf5,
+  0xde, 0xd4, 0xd1, 0xc3, 0xfb, 0x3a, 0x04, 0x66, 0xa4, 0x1e, 0x77, 0x22,
+  0x0a, 0xa8, 0x53, 0xbd, 0x3d, 0x6a, 0x97, 0x88, 0x4e, 0x1f, 0x2e, 0xdd,
+  0x93, 0x08, 0x70, 0x80, 0xdc, 0x1a, 0xe2, 0x50, 0xb7, 0x04, 0x70, 0xa2,
+  0x3b, 0xaf, 0x7c, 0x4e, 0x5f, 0xf9, 0xa9, 0x40, 0x96, 0xce, 0xe4, 0xc4,
+  0x82, 0x69, 0x69, 0xc5, 0x24, 0xa8, 0xd8, 0x4c, 0xc1, 0x67, 0xa2, 0xfb,
+  0x09, 0x11, 0xb8, 0x81, 0xac, 0xd9, 0x67, 0x84, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x02, 0x14, 0x52, 0xe9, 0x66, 0x81,
+  0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82, 0x66, 0xd8, 0x3d, 0x2b,
+  0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0xa2, 0xc0, 0x9e, 0xf9, 0x97, 0xa0, 0xd2, 0xc6, 0x26, 0xab,
+  0x6f, 0xcd, 0xe3, 0x26, 0x9a, 0x84, 0x36, 0x7f, 0xc2, 0x96, 0xd3, 0x86,
+  0xa8, 0x11, 0x5e, 0x7f, 0x51, 0xca, 0x10, 0xd2, 0x2f, 0xa1, 0x77, 0x7f,
+  0x38, 0x4b, 0x29, 0xf3, 0x29, 0xde, 0x40, 0x1f, 0x90, 0xc8, 0x27, 0xda,
+  0xa3, 0x78, 0x32, 0x33, 0x7e, 0x14, 0xd5, 0x64, 0xbf, 0x1c, 0xda, 0x52,
+  0xe1, 0x8b, 0x30, 0xc4, 0x2f, 0x7d, 0x2d, 0x90, 0xbb, 0x48, 0x76, 0xa1,
+  0x43, 0xc4, 0x94, 0x0f, 0x46, 0xc8, 0x59, 0x22, 0xf5, 0x6b, 0x27, 0xb2,
+  0x4e, 0x2a, 0xdb, 0xdf, 0x11, 0x6c, 0xe0, 0x56, 0x35, 0x2e, 0x58, 0x52,
+  0x79, 0xc0, 0x3e, 0x76, 0xe3, 0x0e, 0x85, 0xd1, 0x32, 0xa8, 0x53, 0x5d,
+  0x27, 0x22, 0x2e, 0x15, 0xea, 0x70, 0x6c, 0x2a, 0x73, 0xb8, 0x9b, 0xf8,
+  0xc2, 0x6a, 0x18, 0x47, 0xb6, 0xd7, 0x29, 0xe6, 0x49, 0x0b, 0xdd, 0x4d,
+  0xb4, 0x29, 0xcd, 0xd0, 0xa5, 0x8a, 0xf5, 0xb0, 0x47, 0x07, 0xac, 0xbf,
+  0xca, 0x2e, 0x61, 0x3a, 0xfd, 0xeb, 0xea, 0xc1, 0xe1, 0x92, 0x58, 0x61,
+  0xf7, 0x59, 0x0b, 0x7e, 0x8b, 0xd2, 0x4c, 0xe5, 0xb7, 0xd0, 0xb2, 0xd2,
+  0x33, 0xfa, 0x22, 0xfe, 0x65, 0x42, 0xd6, 0x23, 0xfd, 0xc0, 0x57, 0xc9,
+  0x07, 0x1f, 0x6a, 0x54, 0xa5, 0x52, 0xd8, 0x96, 0x43, 0xc0, 0x43, 0x2b,
+  0x5d, 0x56, 0x92, 0x13, 0x0e, 0x48, 0xcb, 0x13, 0x67, 0x68, 0x59, 0xd9,
+  0xf6, 0xac, 0xc5, 0xe0, 0x38, 0xbb, 0xa9, 0x1d, 0xa2, 0xff, 0x7c, 0xd4,
+  0xb2, 0xef, 0x1e, 0x6b, 0x0c, 0xca, 0x22, 0xa3, 0x74, 0x23, 0xd3, 0x6a,
+  0x98, 0x4c, 0x31, 0xf8, 0xa7, 0x60, 0x16, 0x22, 0xfb, 0x2b, 0x53, 0x6a,
+  0x9a, 0x61, 0xc5, 0x0e, 0x2d, 0xce, 0x21, 0x45, 0x66, 0x03, 0x59, 0x1a,
+  0x6b, 0x04, 0xc4, 0xc7, 0x7f, 0x7c, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94,
+  0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03,
+  0x02, 0x01, 0x02, 0x02, 0x14, 0x38, 0x39, 0x6f, 0x5f, 0x80, 0x6d, 0xcf,
+  0xd1, 0x4e, 0x2f, 0x53, 0x68, 0x40, 0x42, 0xef, 0x69, 0xa1, 0xfe, 0x99,
+  0xf5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
+  0x33, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31,
+  0x30, 0x32, 0x31, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36,
+  0x30, 0x39, 0x31, 0x30, 0x32, 0x31, 0x34, 0x34, 0x5a, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+  0x01, 0x01, 0x00, 0xc5, 0xa4, 0x45, 0xe2, 0xed, 0x42, 0x14, 0xcc, 0x23,
+  0x8f, 0x88, 0xd1, 0x25, 0xad, 0x09, 0xce, 0x76, 0x2a, 0xdf, 0x7f, 0xe5,
+  0x91, 0x68, 0x57, 0x47, 0xfc, 0xc0, 0x89, 0x58, 0xbe, 0x5d, 0xb8, 0xf0,
+  0x27, 0x14, 0xc6, 0x55, 0x1e, 0x77, 0xac, 0xdd, 0xa9, 0x68, 0x3b, 0x5d,
+  0x70, 0x8f, 0x46, 0x23, 0x79, 0x04, 0xaa, 0x4c, 0xac, 0x0b, 0x48, 0x34,
+  0x26, 0xf7, 0x17, 0xa3, 0x60, 0x99, 0x62, 0x20, 0x7f, 0x72, 0x28, 0x48,
+  0x1e, 0x7f, 0x80, 0x31, 0xd6, 0xd3, 0xa2, 0x5c, 0x96, 0xf1, 0x8d, 0x66,
+  0x1c, 0x68, 0x0e, 0x67, 0x17, 0x98, 0x75, 0xc1, 0x02, 0x8f, 0x9f, 0x6b,
+  0x7e, 0x56, 0x8c, 0xfc, 0x09, 0x93, 0xf8, 0xbb, 0x7e, 0x45, 0x8d, 0x29,
+  0x6c, 0xb3, 0xf1, 0x72, 0xf5, 0x51, 0xec, 0x89, 0xfa, 0x1f, 0xfb, 0x58,
+  0x48, 0x7b, 0x04, 0x4e, 0x28, 0xaf, 0x4a, 0xc4, 0x21, 0xc8, 0x4d, 0x16,
+  0x60, 0x7d, 0x56, 0x71, 0x9b, 0x56, 0x29, 0xaa, 0x31, 0xa1, 0x28, 0xa8,
+  0x6e, 0x6e, 0xfe, 0x02, 0xf8, 0x3b, 0x9a, 0xc6, 0xf2, 0xd1, 0x6c, 0xab,
+  0xaf, 0x75, 0xc8, 0xdb, 0xd6, 0x78, 0x66, 0x29, 0x78, 0x67, 0x65, 0x6c,
+  0x9d, 0x21, 0xb9, 0x3d, 0x7f, 0x72, 0x02, 0x8e, 0x00, 0x13, 0xe2, 0x13,
+  0x9f, 0xb8, 0x18, 0xe8, 0x61, 0x7c, 0x55, 0xd3, 0xa5, 0xd9, 0x93, 0x9f,
+  0x93, 0xed, 0x67, 0x5a, 0x1a, 0x1d, 0x01, 0x32, 0xfd, 0xcb, 0x26, 0xac,
+  0xfc, 0x89, 0x71, 0x4d, 0x8f, 0xf2, 0xfb, 0x04, 0xae, 0x0f, 0x8e, 0xbd,
+  0xdf, 0x7f, 0xb8, 0xe5, 0xcb, 0xc4, 0xd7, 0x7b, 0xfd, 0xa1, 0x70, 0x0b,
+  0xd3, 0xe3, 0xcf, 0xf1, 0x70, 0x0e, 0x50, 0xca, 0x54, 0x8c, 0xaf, 0xdc,
+  0xb2, 0x45, 0x82, 0xe4, 0xb6, 0xc7, 0x26, 0x2e, 0x7d, 0x8e, 0x2d, 0xc9,
+  0x2a, 0x22, 0x8e, 0x27, 0x07, 0x32, 0x51, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x95, 0x6e, 0xcf, 0x47, 0x75, 0x35, 0xd0, 0x19, 0xe5,
+  0x5a, 0x9a, 0xb0, 0x88, 0x48, 0xe0, 0xf4, 0xf4, 0x14, 0x3c, 0x85, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x95, 0x6e, 0xcf, 0x47, 0x75, 0x35, 0xd0, 0x19, 0xe5, 0x5a, 0x9a, 0xb0,
+  0x88, 0x48, 0xe0, 0xf4, 0xf4, 0x14, 0x3c, 0x85, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+  0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x86, 0xba, 0x2b,
+  0x96, 0x5e, 0x22, 0x2b, 0xef, 0x74, 0xc6, 0xf2, 0xbc, 0xbe, 0x21, 0xa8,
+  0x27, 0x2a, 0x17, 0x7c, 0xf9, 0xe5, 0xc4, 0x85, 0x15, 0x51, 0xaa, 0xe7,
+  0x2b, 0xe5, 0xda, 0xb6, 0xb4, 0x8f, 0xd3, 0xd1, 0x79, 0x19, 0xfb, 0x50,
+  0x82, 0x44, 0xfc, 0x43, 0xcd, 0xb5, 0x84, 0xa9, 0xfa, 0xe4, 0x46, 0xd3,
+  0x8b, 0x80, 0x5a, 0x7a, 0xb0, 0x2f, 0x13, 0x12, 0x26, 0xa9, 0xb6, 0x15,
+  0x8d, 0x15, 0x37, 0x6f, 0x1e, 0xd2, 0x40, 0xb1, 0xc4, 0x1e, 0x58, 0x92,
+  0xe8, 0xc8, 0x89, 0xe5, 0x1e, 0x5e, 0x2c, 0x55, 0xa9, 0x9e, 0x12, 0xab,
+  0x7c, 0x7b, 0x07, 0xa9, 0xc8, 0x02, 0x72, 0xc1, 0x14, 0xc6, 0x5e, 0xc8,
+  0xf9, 0xa8, 0x3f, 0xd4, 0x66, 0x97, 0x08, 0x34, 0x05, 0x36, 0x66, 0xcf,
+  0x6f, 0x06, 0x56, 0x56, 0x2b, 0xad, 0xb8, 0x13, 0x3f, 0xdb, 0x77, 0xd8,
+  0xd9, 0xf7, 0xb8, 0x12, 0x23, 0xbf, 0xda, 0x11, 0xd9, 0x7d, 0x1d, 0xdc,
+  0x38, 0xd4, 0x01, 0x43, 0x23, 0xea, 0xa4, 0x53, 0x75, 0x53, 0x06, 0xb5,
+  0xc9, 0xd5, 0x44, 0x9f, 0xbc, 0xd8, 0x31, 0xab, 0xb5, 0x5a, 0xb5, 0xbf,
+  0xd2, 0xf9, 0x2a, 0x39, 0xc9, 0x3c, 0x58, 0x7c, 0x50, 0x0e, 0x1d, 0x6e,
+  0x59, 0xf0, 0x94, 0x25, 0x16, 0x44, 0x6c, 0x07, 0x98, 0xc1, 0x02, 0xad,
+  0xb9, 0x1b, 0xac, 0x2f, 0x6b, 0x4a, 0xb3, 0x49, 0xd6, 0xfa, 0xa6, 0x71,
+  0xa4, 0xbc, 0x15, 0xec, 0x7f, 0x4e, 0x6e, 0xfd, 0x61, 0x43, 0x5b, 0xd9,
+  0x89, 0xc7, 0x7a, 0xed, 0xa2, 0x3a, 0x4b, 0x5a, 0x70, 0x82, 0x20, 0xb0,
+  0x98, 0x00, 0x01, 0x5d, 0xae, 0xb2, 0xcc, 0x52, 0xf3, 0x9e, 0x42, 0xc8,
+  0xc0, 0xb1, 0xb6, 0x7a, 0xa3, 0xf1, 0x67, 0xbd, 0x42, 0xdd, 0xa0, 0xda,
+  0x1f, 0x3d, 0xb7, 0xc1, 0x76, 0xfb, 0x3c, 0x4b, 0x5d, 0x16, 0x56, 0x9c,
+  0xc7, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab,
   0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x03,
   0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
-  0x11, 0x90, 0xbd, 0xc1, 0x8a, 0x36, 0x84, 0x80, 0x84, 0xa0, 0xe2, 0x8f,
-  0x57, 0xc9, 0x25, 0x01, 0xd7, 0x71, 0x9f, 0x6f, 0x30, 0x0d, 0x06, 0x09,
+  0x0c, 0x12, 0x5f, 0x58, 0xf0, 0xd3, 0x6a, 0x30, 0x85, 0x33, 0xc6, 0x78,
+  0x6c, 0xba, 0x96, 0x20, 0xfb, 0x14, 0x86, 0x6d, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x33, 0x30, 0x1e, 0x17, 0x0d,
-  0x32, 0x34, 0x30, 0x31, 0x32, 0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38,
-  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32,
-  0x30, 0x30, 0x38, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x4b, 0x45, 0x4b, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x34, 0x35,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x34, 0x35, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4b, 0x45,
+  0x4b, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
   0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
-  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd4, 0x89,
-  0x82, 0x3f, 0x53, 0x8c, 0x94, 0xba, 0xbf, 0xff, 0xfd, 0x18, 0x9b, 0xa0,
-  0x30, 0x7e, 0x56, 0xd7, 0xe1, 0xdb, 0x77, 0x88, 0x35, 0xa8, 0x20, 0x69,
-  0xe2, 0x3a, 0xcf, 0x0b, 0x87, 0xd0, 0x06, 0x39, 0x83, 0x46, 0x15, 0xe8,
-  0x36, 0xf1, 0xf5, 0x3e, 0x46, 0xed, 0xa8, 0x8c, 0x11, 0x33, 0x9f, 0x72,
-  0xc0, 0x57, 0xd0, 0x06, 0x35, 0x06, 0xc7, 0xd5, 0xdb, 0xeb, 0x3d, 0x12,
-  0xc4, 0xc2, 0x0c, 0x5e, 0x14, 0xf4, 0x7c, 0x3a, 0xd8, 0x55, 0x37, 0xcd,
-  0x55, 0x2c, 0x37, 0x98, 0x2b, 0xdb, 0x3b, 0xfe, 0x70, 0x06, 0x56, 0x64,
-  0x03, 0x64, 0x13, 0xd6, 0x73, 0xf3, 0x93, 0x8b, 0xc3, 0x37, 0xa5, 0xb7,
-  0xa0, 0x40, 0xb6, 0x3d, 0x7e, 0x79, 0x86, 0xc6, 0x33, 0x3c, 0x2a, 0x5a,
-  0x0f, 0x91, 0x91, 0xef, 0xdb, 0xca, 0x47, 0x58, 0x83, 0xde, 0x22, 0x81,
-  0x8f, 0x19, 0x49, 0x6f, 0x3b, 0xae, 0x06, 0xad, 0xda, 0xb6, 0xad, 0x04,
-  0x62, 0xe2, 0xb0, 0x14, 0xc4, 0xb0, 0xc3, 0x7d, 0x2f, 0x48, 0x19, 0x75,
-  0xd0, 0xda, 0x81, 0x60, 0x0d, 0x03, 0xbd, 0x1b, 0xfd, 0xb6, 0x10, 0x7b,
-  0x23, 0x4e, 0x91, 0xa6, 0xff, 0xbd, 0xd5, 0xfe, 0xd7, 0x3f, 0x63, 0x53,
-  0x1f, 0x48, 0xe5, 0xc9, 0x6d, 0x69, 0xcd, 0x0e, 0xde, 0x54, 0xe3, 0x42,
-  0xb6, 0xdc, 0x12, 0x2e, 0x0c, 0xcf, 0x40, 0x58, 0x52, 0xef, 0xad, 0x8d,
-  0xf4, 0x52, 0x56, 0xda, 0x3b, 0x47, 0xb1, 0x4c, 0xc6, 0xe1, 0x3a, 0x6f,
-  0x28, 0xe9, 0xf9, 0x10, 0x86, 0x37, 0x24, 0x74, 0xe5, 0x03, 0xb1, 0x95,
-  0x71, 0xe4, 0xf4, 0xe5, 0xaa, 0xb3, 0x88, 0x15, 0x20, 0x3c, 0xc8, 0x00,
-  0x2d, 0x04, 0x4a, 0x7e, 0x35, 0x7c, 0x70, 0xb1, 0xa6, 0xad, 0x82, 0xa0,
-  0x77, 0xb5, 0x4d, 0xd4, 0x92, 0x0c, 0x9a, 0xca, 0x8b, 0xdd, 0x75, 0x28,
-  0xae, 0x99, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
-  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xae, 0xfa,
-  0xbf, 0x66, 0xb9, 0xc6, 0xf2, 0x3b, 0x01, 0x7f, 0x52, 0x90, 0x41, 0x6d,
-  0x0e, 0x33, 0x51, 0x01, 0x7c, 0x7e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
-  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xae, 0xfa, 0xbf, 0x66, 0xb9,
-  0xc6, 0xf2, 0x3b, 0x01, 0x7f, 0x52, 0x90, 0x41, 0x6d, 0x0e, 0x33, 0x51,
-  0x01, 0x7c, 0x7e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc0, 0x81,
+  0x99, 0xa7, 0xb3, 0xc2, 0xbb, 0x60, 0xb5, 0x3a, 0x4d, 0x56, 0x24, 0xbe,
+  0xcf, 0xd6, 0x93, 0x58, 0xba, 0xc4, 0x6d, 0x7a, 0x7a, 0x40, 0xeb, 0xcc,
+  0x19, 0x03, 0x10, 0x18, 0xaf, 0x50, 0x59, 0xdd, 0x2e, 0x08, 0x04, 0x07,
+  0xc8, 0x54, 0x6d, 0x39, 0xf9, 0x64, 0x50, 0xe3, 0x56, 0x30, 0x72, 0xe6,
+  0x2c, 0x00, 0xea, 0x0e, 0xa6, 0x34, 0x8f, 0x45, 0x36, 0xe7, 0x50, 0x66,
+  0xe1, 0x48, 0xb3, 0x15, 0x44, 0x80, 0x19, 0x0c, 0x0a, 0x39, 0x79, 0x81,
+  0x77, 0xe3, 0x4f, 0x2e, 0xdb, 0x9a, 0xbe, 0xdc, 0xa8, 0xf4, 0x68, 0xc2,
+  0xdc, 0x2d, 0x82, 0x6c, 0x9a, 0xd0, 0x5b, 0xc5, 0xe6, 0x6b, 0x8d, 0x47,
+  0xe0, 0xa1, 0x1a, 0x60, 0x77, 0x5e, 0x43, 0x07, 0x54, 0xd8, 0xf4, 0xa6,
+  0x39, 0x05, 0x81, 0x81, 0xf4, 0xae, 0xeb, 0xa2, 0x3b, 0x10, 0xfa, 0x4d,
+  0xfe, 0x36, 0x8c, 0x97, 0x63, 0xd9, 0x5a, 0xac, 0xb3, 0xb3, 0x00, 0x92,
+  0x05, 0x2b, 0x40, 0x1e, 0x19, 0x82, 0x95, 0x88, 0xc1, 0x12, 0x8b, 0x75,
+  0xd0, 0x2e, 0x7d, 0xff, 0xaa, 0xfa, 0x42, 0x06, 0x65, 0xe4, 0xf6, 0x53,
+  0xc5, 0xfc, 0x27, 0xc7, 0xa5, 0x7e, 0x53, 0x16, 0x14, 0xb4, 0xc1, 0x0d,
+  0xb0, 0xe2, 0x68, 0x7b, 0x4f, 0x12, 0x73, 0x8e, 0x83, 0xde, 0x87, 0xd7,
+  0xa4, 0xa5, 0x89, 0x47, 0xc8, 0x0c, 0xfc, 0x97, 0xe3, 0x7f, 0xac, 0x9a,
+  0x0e, 0x6d, 0xb0, 0x30, 0x81, 0xf5, 0x44, 0x30, 0x9f, 0xf1, 0x35, 0x74,
+  0x9a, 0xd6, 0xa9, 0x3f, 0x7b, 0xda, 0xb6, 0x6c, 0x57, 0xf3, 0x30, 0x79,
+  0x28, 0xf1, 0x80, 0x59, 0x74, 0x89, 0x8e, 0x47, 0xdb, 0x18, 0x88, 0xcc,
+  0x70, 0xe8, 0x83, 0xc9, 0x71, 0x4a, 0x98, 0x70, 0x59, 0x75, 0xb6, 0xc0,
+  0x38, 0x4c, 0x99, 0xd6, 0xcf, 0x7d, 0xa5, 0x7e, 0x31, 0x0c, 0x2c, 0xec,
+  0x40, 0x33, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa3, 0xa7,
+  0xec, 0x3a, 0x10, 0xec, 0x88, 0xfd, 0x73, 0x14, 0x02, 0xf7, 0x0d, 0x93,
+  0x72, 0x23, 0xdb, 0x2b, 0x6d, 0xd3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xa3, 0xa7, 0xec, 0x3a, 0x10,
+  0xec, 0x88, 0xfd, 0x73, 0x14, 0x02, 0xf7, 0x0d, 0x93, 0x72, 0x23, 0xdb,
+  0x2b, 0x6d, 0xd3, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
   0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
-  0x82, 0x01, 0x01, 0x00, 0xb8, 0xdb, 0x9a, 0x38, 0x6e, 0xb1, 0x48, 0xe0,
-  0x5a, 0x9b, 0xd5, 0xec, 0x2e, 0xe5, 0x8a, 0xb5, 0xc7, 0x4e, 0x9f, 0xe9,
-  0x8d, 0xde, 0x11, 0xc5, 0xe0, 0x8a, 0x75, 0xe6, 0x04, 0x7e, 0xfa, 0xcb,
-  0x3e, 0xa2, 0xb8, 0x28, 0xf3, 0xbc, 0xc5, 0xaf, 0x6d, 0x2a, 0x45, 0x34,
-  0x91, 0x62, 0xf5, 0xe1, 0x66, 0x7f, 0x82, 0xd9, 0xac, 0xc4, 0x29, 0x36,
-  0xed, 0xcb, 0x8a, 0x97, 0x88, 0x6c, 0x8f, 0xa1, 0x19, 0xbd, 0x04, 0xe1,
-  0x1c, 0x95, 0x7f, 0x45, 0xe3, 0x8c, 0xda, 0x74, 0xa7, 0xd9, 0x4d, 0x41,
-  0x34, 0x96, 0x77, 0xe0, 0x68, 0xd7, 0x7b, 0xff, 0x62, 0x1d, 0xa3, 0xaf,
-  0x12, 0xdc, 0x6a, 0xf1, 0xaf, 0x09, 0xa2, 0xc6, 0x72, 0xa4, 0xbb, 0xcf,
-  0xd4, 0x96, 0xae, 0x41, 0xfc, 0x77, 0x56, 0xe7, 0xe0, 0x8e, 0x0a, 0x80,
-  0xd5, 0xc1, 0xb4, 0xfd, 0xa9, 0xf4, 0x8d, 0xc8, 0x26, 0xf8, 0x21, 0x0b,
-  0x8c, 0xc3, 0x6a, 0x75, 0x46, 0xf2, 0x3f, 0x5c, 0x42, 0xd6, 0xe4, 0x98,
-  0x73, 0x72, 0x9a, 0x34, 0x71, 0x4f, 0xa2, 0x97, 0x2e, 0x63, 0x1f, 0x38,
-  0x25, 0x1c, 0xb8, 0xf8, 0xec, 0xc0, 0x60, 0x14, 0x9a, 0x9d, 0x91, 0xc0,
-  0x0e, 0xbb, 0x23, 0xfc, 0x25, 0x8b, 0x01, 0x20, 0x2d, 0x30, 0x0f, 0x25,
-  0xa7, 0x0a, 0xbe, 0x91, 0xf3, 0xb5, 0x15, 0x77, 0x07, 0x59, 0x4a, 0x3a,
-  0xc7, 0x1b, 0xb9, 0xc9, 0x48, 0xa4, 0xfe, 0x05, 0xe2, 0x50, 0x89, 0x26,
-  0xd8, 0x13, 0xe1, 0xd2, 0xe4, 0x5d, 0x34, 0xa3, 0x8f, 0x99, 0x00, 0xd0,
-  0x11, 0x13, 0x97, 0x4c, 0x41, 0x2d, 0x63, 0xdf, 0xb6, 0xa6, 0xc1, 0xb5,
-  0x9f, 0x08, 0xda, 0x44, 0xd1, 0x80, 0x1d, 0xe3, 0x82, 0x12, 0x5e, 0xa8,
-  0x63, 0x8f, 0x74, 0xf2, 0xab, 0xbb, 0xf6, 0xca, 0x2a, 0x51, 0xa2, 0xc2,
-  0xcc, 0x85, 0x37, 0x85, 0x97, 0x1a, 0x4c, 0x3e, 0xa1, 0x59, 0xc0, 0xa5,
-  0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72,
-  0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x15, 0xc4, 0x07, 0x64, 0x88,
-  0x06, 0x82, 0x9c, 0x3c, 0x2d, 0x78, 0x10, 0xb2, 0xe0, 0xd2, 0x9e, 0x71,
-  0x1d, 0x2f, 0xa4, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x4b, 0x45, 0x4b, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
-  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x4b, 0x45, 0x4b, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xb1, 0x58, 0xde, 0xa8, 0xfb, 0xf9, 0xd2,
-  0x48, 0x11, 0x0a, 0x52, 0x68, 0xbf, 0x45, 0x97, 0xde, 0xdf, 0x54, 0xb3,
-  0x6e, 0x36, 0xc5, 0x3a, 0xbb, 0x40, 0x18, 0x66, 0xa7, 0x0e, 0x5d, 0xb1,
-  0x7a, 0x56, 0x24, 0xc7, 0x0d, 0x7e, 0x37, 0xba, 0x60, 0x6d, 0xf6, 0x81,
-  0x0a, 0x3d, 0x42, 0xec, 0x79, 0x49, 0x9a, 0x1c, 0x20, 0x08, 0x17, 0xc7,
-  0xba, 0x26, 0xc1, 0x71, 0x47, 0xc0, 0xe6, 0x29, 0xb8, 0xd0, 0x4f, 0xe9,
-  0xd2, 0x6f, 0x18, 0x49, 0x9d, 0xfc, 0x4a, 0xcc, 0x26, 0x74, 0xc6, 0x1e,
-  0xe7, 0x9c, 0x43, 0x2e, 0x09, 0xe0, 0x5a, 0x60, 0xa2, 0x27, 0xc0, 0x14,
-  0x32, 0x3d, 0xe4, 0x64, 0xf9, 0x25, 0x6b, 0x9c, 0x7a, 0x01, 0xea, 0xdf,
-  0x71, 0x26, 0xf8, 0x14, 0x89, 0xa0, 0x80, 0xf4, 0x8a, 0x05, 0x54, 0xc4,
-  0x9a, 0x7b, 0x32, 0x5e, 0x75, 0x0d, 0x1b, 0x8a, 0x38, 0x5c, 0x64, 0x7c,
-  0xf0, 0x65, 0x9e, 0xdf, 0x58, 0xaa, 0x71, 0xff, 0xc1, 0x20, 0xe1, 0x4b,
-  0x48, 0x68, 0x71, 0x4b, 0xfc, 0xef, 0x39, 0x8d, 0xae, 0x58, 0x97, 0x65,
-  0xb5, 0x44, 0x65, 0x33, 0x93, 0xa6, 0xc2, 0xf7, 0x3c, 0x23, 0x25, 0x47,
-  0x9c, 0x7b, 0xd8, 0x12, 0xbc, 0xba, 0xce, 0xfe, 0x07, 0xe1, 0xc2, 0x9a,
-  0x43, 0xb1, 0x09, 0x74, 0xea, 0xdd, 0x81, 0x9a, 0x66, 0xe9, 0x6f, 0x75,
-  0x8b, 0x63, 0x09, 0x9c, 0xf0, 0x85, 0x72, 0xe5, 0x2a, 0x9f, 0x3e, 0x03,
-  0xa2, 0x11, 0x73, 0xd5, 0xd0, 0x24, 0x59, 0x74, 0x10, 0x45, 0xcf, 0xe0,
-  0xb1, 0x3b, 0x35, 0x13, 0x92, 0x60, 0xba, 0x75, 0x1e, 0x39, 0xa2, 0x18,
-  0xb5, 0x23, 0xf6, 0xc1, 0x74, 0x5d, 0x73, 0x17, 0xea, 0xca, 0xdb, 0xc8,
-  0xc9, 0x9b, 0xf9, 0x83, 0x44, 0x29, 0x0d, 0xb2, 0xd1, 0x8e, 0x8f, 0xbb,
-  0xd4, 0x42, 0x43, 0x3d, 0xc1, 0x0f, 0xb0, 0x97, 0xaf, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0xe7, 0x8d, 0x45, 0x79, 0xdf, 0xb1, 0x92,
-  0x11, 0x72, 0x87, 0x8b, 0x78, 0xf8, 0xa7, 0x0a, 0x5b, 0x96, 0x87, 0x09,
-  0x5b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0xe7, 0x8d, 0x45, 0x79, 0xdf, 0xb1, 0x92, 0x11, 0x72, 0x87,
-  0x8b, 0x78, 0xf8, 0xa7, 0x0a, 0x5b, 0x96, 0x87, 0x09, 0x5b, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x09,
-  0x51, 0x16, 0xf4, 0xd7, 0x79, 0xb5, 0xb7, 0x8b, 0x0d, 0x92, 0xc1, 0x9b,
-  0x0a, 0x19, 0x33, 0x4c, 0xf1, 0x00, 0x6a, 0xcd, 0x8f, 0xa5, 0xd0, 0x6e,
-  0x3e, 0x69, 0x35, 0x38, 0xb4, 0xb5, 0x44, 0x54, 0x36, 0x19, 0x58, 0xa8,
-  0xf4, 0x7e, 0xac, 0x8d, 0x41, 0x28, 0x79, 0x67, 0x7f, 0x0e, 0xbc, 0x6f,
-  0xa8, 0x96, 0x5c, 0x9e, 0xe3, 0x3f, 0x31, 0x4a, 0xa5, 0xb0, 0xfd, 0x1e,
-  0xbb, 0x0a, 0xc9, 0x53, 0x84, 0xf3, 0xa2, 0xe5, 0x1c, 0x80, 0x0a, 0xc5,
-  0x78, 0x5f, 0xe2, 0x52, 0xae, 0x36, 0x03, 0x98, 0x73, 0x3c, 0xb0, 0xf3,
-  0xd9, 0xc2, 0x95, 0x68, 0x03, 0xcd, 0xc7, 0x6b, 0x2f, 0x33, 0x38, 0xb5,
-  0x5a, 0x9b, 0xe7, 0x29, 0x23, 0xb1, 0x6c, 0xa2, 0x9e, 0x8d, 0xee, 0x85,
-  0x0d, 0x08, 0x16, 0xdd, 0x64, 0x56, 0x34, 0x81, 0xf1, 0x60, 0x9d, 0x2c,
-  0xed, 0x12, 0xb4, 0x9a, 0x75, 0xfe, 0xc1, 0x3e, 0x8c, 0xf1, 0x59, 0xbd,
-  0xf5, 0x35, 0xe2, 0xb6, 0x97, 0xaa, 0x57, 0x9b, 0xef, 0x1d, 0xf5, 0xd7,
-  0x81, 0x45, 0x41, 0x92, 0x6b, 0x68, 0x8c, 0xeb, 0x78, 0x3f, 0x9e, 0xff,
-  0x30, 0x4a, 0xd8, 0x84, 0x8d, 0x12, 0x4e, 0xbe, 0x2d, 0x87, 0xc4, 0x3a,
-  0xc6, 0x28, 0x10, 0x56, 0xab, 0x73, 0xce, 0xb4, 0xcc, 0xe6, 0x97, 0x77,
-  0xa9, 0x47, 0xa2, 0xd5, 0x05, 0x91, 0x2a, 0xcc, 0xe6, 0x0c, 0xf5, 0xd3,
-  0xb5, 0x97, 0xb3, 0x5a, 0x9e, 0xa1, 0x60, 0x1a, 0xfb, 0x11, 0x8b, 0xa8,
-  0x63, 0x4a, 0x2b, 0xc5, 0xb3, 0x4f, 0xff, 0xaf, 0x88, 0x15, 0x6c, 0xe7,
-  0xba, 0x19, 0x6a, 0xd3, 0xc3, 0xfd, 0x31, 0x96, 0x9c, 0x91, 0xba, 0xe9,
-  0xea, 0xf5, 0x60, 0xda, 0xe9, 0x11, 0xc7, 0x36, 0x2e, 0xf4, 0x1a, 0xde,
-  0x1a, 0xf7, 0x38, 0x9b, 0x68, 0xa2, 0x86, 0x1e, 0x34, 0x5d, 0x19, 0x9b,
-  0x82, 0x03, 0xe5
+  0x82, 0x01, 0x01, 0x00, 0xa8, 0x34, 0xda, 0xa3, 0xda, 0x94, 0xda, 0xcf,
+  0xde, 0x1d, 0x83, 0xa2, 0x0f, 0x94, 0x15, 0xae, 0x1f, 0xda, 0x68, 0xa4,
+  0x42, 0x3c, 0xac, 0x7e, 0xff, 0x08, 0x05, 0x32, 0x5e, 0x08, 0x0d, 0xd9,
+  0x3d, 0xbe, 0x06, 0xf2, 0xa7, 0xd7, 0xef, 0xe2, 0xf5, 0xbc, 0x83, 0x6b,
+  0x18, 0x50, 0xe0, 0x16, 0xe6, 0xe9, 0x99, 0x19, 0xd3, 0xd5, 0xae, 0x48,
+  0x42, 0x59, 0x86, 0x0b, 0xa0, 0xee, 0x0c, 0xdb, 0x74, 0xc2, 0xe3, 0x37,
+  0xc5, 0xd3, 0xa8, 0xba, 0xcf, 0x93, 0x3d, 0xb5, 0x49, 0x1e, 0x45, 0xd7,
+  0x58, 0xa1, 0x82, 0xbd, 0xa7, 0x9a, 0x56, 0x9b, 0x34, 0x16, 0x96, 0xac,
+  0xa1, 0xfe, 0xe4, 0xff, 0x32, 0x4b, 0x69, 0xd9, 0x2c, 0xa8, 0x6a, 0xbd,
+  0x96, 0xf4, 0xc6, 0x4d, 0xb6, 0x43, 0xfd, 0x06, 0xab, 0xf4, 0xb4, 0x77,
+  0xae, 0xfe, 0x1b, 0x5d, 0x50, 0x8b, 0x75, 0x7e, 0xc6, 0xe2, 0x72, 0x1c,
+  0x0f, 0x1f, 0x7a, 0x0c, 0xdd, 0x55, 0xc4, 0x31, 0x57, 0x9d, 0xc0, 0x27,
+  0x36, 0xb5, 0x2c, 0xeb, 0xb6, 0xd7, 0xd5, 0xee, 0x68, 0x6b, 0xdf, 0xf4,
+  0xaa, 0x42, 0xd7, 0xf4, 0x65, 0x97, 0x94, 0xd8, 0x4a, 0x0c, 0xa8, 0xda,
+  0xcc, 0xe9, 0xc1, 0xd5, 0x83, 0x41, 0xcd, 0xb2, 0x26, 0xbe, 0x7b, 0xbe,
+  0x7b, 0x8e, 0x07, 0x32, 0x56, 0x44, 0xa4, 0xaf, 0xf0, 0xca, 0xb5, 0x27,
+  0xfa, 0xa5, 0x6e, 0x1b, 0x9c, 0xcd, 0x5c, 0x4e, 0xd8, 0x36, 0xd2, 0x3d,
+  0xa3, 0x80, 0x40, 0x66, 0x69, 0x46, 0x7e, 0x88, 0xd5, 0x3d, 0x11, 0x84,
+  0x85, 0x6b, 0x97, 0xd2, 0x26, 0x4c, 0x20, 0x3d, 0xb1, 0xee, 0x3e, 0x36,
+  0x8b, 0xd1, 0x37, 0xa7, 0xb3, 0x79, 0x5c, 0xef, 0x7b, 0x69, 0x18, 0xdc,
+  0xcd, 0x8a, 0xbb, 0x1c, 0x53, 0x1f, 0x9b, 0xa8, 0x3c, 0xfa, 0x89, 0xc0,
+  0x16, 0xa2, 0x0a, 0xb0, 0x2b, 0xcd, 0x03, 0x13
 };
-unsigned int KEK_auth_len = 2871;
+unsigned int KEK_auth_len = 2852;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/KEK_delete.h b/components/service/uefi/smm_variable/test/service/auth_vectors/KEK_delete.h
index 7a438a2..219ec1b 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/KEK_delete.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/KEK_delete.h
@@ -7,108 +7,106 @@
  */
 
 unsigned char KEK_delete_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0,
-  0x7a, 0xa6, 0xe6, 0x9b, 0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b,
-  0xc7, 0xa8, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x52, 0xe9, 0x66, 0x81, 0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82,
+  0x66, 0xd8, 0x3d, 0x2b, 0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xcb, 0x94, 0x4f, 0x33, 0x47, 0xe3, 0xb3,
-  0xd0, 0x34, 0x45, 0x48, 0xea, 0x6c, 0x66, 0x8d, 0xb0, 0x97, 0x41, 0xe8,
-  0x81, 0x7f, 0xab, 0x83, 0xa5, 0x9f, 0xa6, 0x5d, 0x47, 0x9b, 0x60, 0x55,
-  0xc3, 0x70, 0x2c, 0xf5, 0x96, 0x9f, 0xa8, 0xdb, 0xc0, 0xca, 0x63, 0x7c,
-  0x34, 0xed, 0x14, 0x9e, 0xc0, 0xbe, 0xab, 0xe4, 0x3b, 0x73, 0xed, 0x62,
-  0x24, 0xe8, 0x68, 0xa4, 0x14, 0x10, 0x50, 0x8f, 0x7f, 0x59, 0xad, 0xec,
-  0x16, 0x60, 0xfe, 0x1f, 0x60, 0x3b, 0x9a, 0x7b, 0x7a, 0xc3, 0x3e, 0xf4,
-  0xcf, 0x39, 0x27, 0x70, 0xb9, 0xd9, 0x0a, 0x40, 0xc7, 0x7f, 0x41, 0x80,
-  0xd3, 0xe0, 0x22, 0x15, 0x1a, 0x91, 0x0e, 0x4a, 0xa7, 0x52, 0x33, 0x72,
-  0xf2, 0x46, 0x03, 0x42, 0x36, 0x85, 0x27, 0xf0, 0x2f, 0x9f, 0x56, 0xa4,
-  0xd5, 0xdc, 0x00, 0xd5, 0x5e, 0xe5, 0x1a, 0x08, 0xae, 0xdc, 0x80, 0xb9,
-  0xa4, 0xcf, 0x58, 0xf1, 0xd4, 0x38, 0x5f, 0xe1, 0xff, 0x81, 0x01, 0xff,
-  0x17, 0x77, 0xe7, 0x4b, 0xee, 0x91, 0xaf, 0x3a, 0xf9, 0x73, 0xd9, 0x6f,
-  0xe9, 0x22, 0x55, 0x15, 0x17, 0xa9, 0xc9, 0xde, 0xfc, 0x63, 0xfc, 0x84,
-  0x96, 0xb7, 0xf8, 0x40, 0x63, 0x5f, 0x2c, 0x21, 0x20, 0x1e, 0x37, 0x14,
-  0x1b, 0x4e, 0x76, 0xec, 0x3a, 0xcb, 0xd5, 0xdc, 0xef, 0x96, 0x37, 0x43,
-  0x46, 0x4c, 0x2e, 0xf4, 0xcb, 0x58, 0x90, 0x91, 0x35, 0x6d, 0xb5, 0x58,
-  0xb8, 0xb7, 0x74, 0x72, 0x80, 0x3f, 0xb7, 0xd0, 0x1b, 0xca, 0x47, 0x18,
-  0xc9, 0x99, 0x4d, 0x74, 0x97, 0x57, 0xc4, 0x2f, 0x2e, 0x2a, 0xd0, 0x95,
-  0xc2, 0x1e, 0x64, 0x8d, 0xbd, 0xd1, 0x7e, 0xf6, 0x6c, 0x44, 0x01, 0x1f,
-  0x37, 0xc0, 0x67, 0x7a, 0x78, 0x47, 0x21, 0xb4, 0x0d, 0xc6, 0xab, 0x81,
-  0x7e, 0x1c, 0x10, 0x5d, 0x01, 0x2e, 0xfe, 0x41, 0x93, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4,
-  0xbb, 0x06, 0xa7, 0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66,
-  0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4, 0xbb, 0x06, 0xa7,
-  0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66, 0x08, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3a,
-  0xae, 0xa0, 0xfa, 0x34, 0x4a, 0x52, 0x24, 0x90, 0x3a, 0xba, 0x33, 0x61,
-  0x0f, 0xc8, 0x6f, 0xbc, 0x72, 0xf8, 0xc3, 0x98, 0x04, 0xe1, 0xcb, 0xf2,
-  0x82, 0xfd, 0x83, 0x59, 0x51, 0x23, 0x71, 0xf4, 0xce, 0xe9, 0x36, 0x4d,
-  0x0a, 0xd3, 0x11, 0x6d, 0x51, 0xb7, 0xd1, 0x9f, 0x9b, 0x85, 0x5c, 0x25,
-  0x11, 0x9c, 0x13, 0xf6, 0x33, 0xd8, 0xa4, 0x27, 0xef, 0x90, 0x56, 0x21,
-  0xe3, 0x90, 0x10, 0x2b, 0x50, 0x46, 0x6e, 0x8a, 0x84, 0x3e, 0x30, 0x4c,
-  0xc2, 0xdf, 0x81, 0x60, 0xdf, 0xb8, 0x06, 0xd8, 0x2f, 0xcf, 0x3f, 0xb8,
-  0xbe, 0x04, 0xa4, 0xbb, 0xba, 0x65, 0x9f, 0x4e, 0xc4, 0x05, 0xbe, 0x9e,
-  0xfe, 0xa9, 0x0c, 0x06, 0x81, 0xcc, 0xa4, 0x66, 0xb0, 0x14, 0x48, 0xc9,
-  0x24, 0x88, 0xd8, 0xdc, 0xf2, 0x5c, 0xb5, 0x59, 0x66, 0x4f, 0xc6, 0xa4,
-  0xa3, 0x96, 0xa8, 0x48, 0x3b, 0x43, 0xff, 0xe0, 0x10, 0x53, 0x79, 0x47,
-  0x74, 0xe8, 0xbc, 0xa9, 0x4f, 0x8e, 0x1f, 0xfb, 0xf8, 0xad, 0x8d, 0x10,
-  0x80, 0x8f, 0x80, 0xf8, 0x5b, 0x36, 0xff, 0x60, 0x0b, 0x3f, 0xb2, 0x2f,
-  0x46, 0x27, 0x43, 0x00, 0x1a, 0x0d, 0xb8, 0x91, 0x4e, 0x84, 0xb1, 0x94,
-  0xc2, 0xca, 0xd6, 0x36, 0x4d, 0xc6, 0xda, 0x53, 0x71, 0xcc, 0xc8, 0x8e,
-  0x9c, 0xdb, 0x31, 0xbb, 0x93, 0x49, 0xa7, 0xf4, 0x0b, 0x19, 0xcb, 0xaa,
-  0x2b, 0x0c, 0xf4, 0xc7, 0x59, 0x8a, 0xc6, 0x59, 0x0b, 0x1d, 0x2f, 0xc3,
-  0xcf, 0x06, 0xcf, 0x2e, 0x6b, 0x15, 0x6f, 0xba, 0xd1, 0xfa, 0x7d, 0x7f,
-  0xaa, 0x99, 0x09, 0x63, 0xa8, 0xdd, 0x6c, 0xdb, 0x6a, 0x5e, 0x00, 0x5e,
-  0x89, 0x11, 0xe3, 0xbd, 0xf6, 0xcb, 0x13, 0x89, 0x6a, 0xb8, 0x7e, 0x89,
-  0xbc, 0xa5, 0xec, 0x68, 0x85, 0xf0, 0xaa, 0x05, 0x91, 0xc1, 0x79, 0xa1,
-  0x1c, 0x9d, 0x32, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x33, 0x39,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x33, 0x39, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
   0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x31, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0, 0x7a, 0xa6, 0xe6, 0x9b,
-  0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b, 0xc7, 0xa8, 0x37, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x79, 0xb7, 0xf1,
-  0xd7, 0x10, 0x57, 0xa4, 0x67, 0x2a, 0x91, 0xef, 0x0a, 0xc7, 0x5d, 0xab,
-  0x08, 0x42, 0x15, 0xc0, 0x26, 0xe7, 0x5d, 0xf1, 0xeb, 0xb1, 0x12, 0xc6,
-  0x2e, 0x06, 0xef, 0x46, 0x84, 0x4c, 0xde, 0x5e, 0xcb, 0x15, 0xe0, 0x19,
-  0x9e, 0x90, 0xdf, 0x92, 0x11, 0x55, 0xb5, 0x50, 0x34, 0xf4, 0xfd, 0x6c,
-  0x76, 0x08, 0xb6, 0x0b, 0xd8, 0x82, 0x4a, 0x8c, 0xc5, 0x4f, 0xc8, 0x56,
-  0xbe, 0xca, 0xac, 0xcb, 0xe9, 0x11, 0x28, 0xf5, 0xde, 0x21, 0x37, 0x2c,
-  0x5b, 0xaa, 0x7f, 0x8a, 0x27, 0xd7, 0xad, 0xba, 0xb6, 0x6d, 0x98, 0x59,
-  0x04, 0xd9, 0x05, 0xa1, 0xab, 0x50, 0xc9, 0x3c, 0xaf, 0x9f, 0x00, 0xad,
-  0x06, 0x76, 0x07, 0x95, 0x6b, 0x34, 0xf3, 0xbe, 0xe3, 0xa1, 0xc2, 0xf9,
-  0x03, 0xee, 0x35, 0xa8, 0xa8, 0xbb, 0x9b, 0xdf, 0xc6, 0x41, 0xff, 0xd1,
-  0x97, 0x00, 0xfd, 0x58, 0xb0, 0xcc, 0x63, 0x5f, 0x91, 0xc0, 0xb7, 0x4d,
-  0xb1, 0xbd, 0x57, 0xfc, 0xfe, 0xa3, 0x6b, 0xd8, 0xdf, 0xd4, 0x57, 0x12,
-  0x31, 0x0b, 0x64, 0xd8, 0xd9, 0xcd, 0xde, 0xa6, 0x6c, 0x7b, 0xb3, 0x05,
-  0x25, 0xd2, 0x0a, 0x9f, 0xc1, 0xf3, 0xcb, 0xa7, 0x7d, 0x79, 0x6a, 0x3d,
-  0xdd, 0x16, 0xac, 0xdc, 0x46, 0xb4, 0x76, 0x7f, 0xe5, 0x8b, 0x7c, 0xc4,
-  0xc9, 0x59, 0x40, 0xa6, 0x75, 0x19, 0xb6, 0xa1, 0x43, 0xa6, 0x79, 0x2c,
-  0xa3, 0x47, 0x02, 0x1c, 0xdb, 0x39, 0xa0, 0x4b, 0x94, 0xfa, 0x0c, 0x56,
-  0xea, 0x32, 0x2e, 0x26, 0x44, 0xf6, 0x22, 0xdc, 0x12, 0x0d, 0x91, 0x98,
-  0x2d, 0x28, 0x7c, 0x68, 0xc8, 0x2f, 0xbd, 0x7b, 0xa2, 0x6d, 0xfa, 0x77,
-  0xd6, 0xf3, 0xcd, 0xb7, 0xd6, 0x0e, 0xd7, 0x4f, 0x8c, 0x13, 0xf6, 0x82,
-  0x51, 0x03, 0xd6, 0x09, 0xfd, 0x82, 0xd7, 0x7e, 0xa1, 0xbe, 0x10, 0x0a,
-  0x7c
+  0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb4, 0xbd,
+  0xd5, 0x2a, 0xdb, 0x3a, 0x4d, 0x37, 0x36, 0x4d, 0xbd, 0x2d, 0xdd, 0x31,
+  0xa0, 0x7c, 0x7b, 0x7e, 0xe9, 0x55, 0x50, 0x4b, 0xe5, 0x61, 0x69, 0x6e,
+  0x08, 0xe2, 0x82, 0x54, 0xfb, 0x00, 0xb6, 0x47, 0x01, 0x5c, 0x5b, 0x73,
+  0xa3, 0xde, 0x30, 0xa7, 0xd9, 0x8c, 0xeb, 0x4f, 0xda, 0x0a, 0x94, 0xc1,
+  0xd3, 0x97, 0x5c, 0xa7, 0x6f, 0x9e, 0xaa, 0xec, 0xa4, 0xf6, 0x8e, 0x73,
+  0x60, 0xe3, 0xac, 0xf7, 0x7e, 0x9b, 0x08, 0x30, 0x52, 0xff, 0x95, 0xb3,
+  0x7f, 0xf6, 0x6d, 0x5f, 0xa3, 0xcd, 0xa6, 0x56, 0x71, 0x33, 0xd0, 0xb4,
+  0xff, 0x03, 0x8c, 0xb2, 0x32, 0x91, 0x48, 0x85, 0x24, 0xd0, 0x68, 0x4c,
+  0xce, 0x62, 0xea, 0xca, 0xad, 0xa7, 0x72, 0x35, 0x14, 0xc3, 0x1d, 0x0a,
+  0x36, 0xb0, 0xd4, 0xcb, 0xd8, 0x0c, 0x98, 0xb9, 0x5f, 0x9b, 0xaa, 0x68,
+  0x27, 0xfc, 0xe2, 0xa0, 0x36, 0xee, 0xbc, 0x64, 0xfe, 0x8c, 0x50, 0xff,
+  0xb1, 0x4b, 0x68, 0xcb, 0x94, 0x38, 0x30, 0x9d, 0x67, 0x62, 0x55, 0x1e,
+  0x63, 0x79, 0x1b, 0xad, 0xd2, 0x5e, 0xb6, 0x5f, 0xb2, 0xc5, 0x0d, 0x9d,
+  0x4d, 0xc8, 0xa4, 0xfc, 0x83, 0x5e, 0x18, 0xee, 0xd1, 0xd7, 0x76, 0xe4,
+  0xb0, 0x2b, 0xd0, 0x2c, 0x17, 0xc9, 0x90, 0xe8, 0x80, 0x55, 0x57, 0xbb,
+  0x0a, 0x46, 0x21, 0x7e, 0x3b, 0x14, 0x77, 0xf0, 0xd8, 0x0c, 0x16, 0x37,
+  0x83, 0x8e, 0x1f, 0x4f, 0xaa, 0x00, 0x5c, 0x5d, 0x47, 0xd4, 0xcf, 0x73,
+  0x86, 0x3c, 0x58, 0x87, 0x82, 0xb1, 0x1d, 0x23, 0xac, 0x24, 0x76, 0xc8,
+  0xcb, 0xca, 0x4f, 0xd6, 0xf0, 0x8f, 0xcd, 0xa9, 0x63, 0xce, 0x57, 0x71,
+  0x88, 0xba, 0x20, 0x04, 0x94, 0x83, 0x87, 0x97, 0xc7, 0xd1, 0xdf, 0xc1,
+  0x1c, 0x07, 0x3f, 0x08, 0x53, 0x11, 0x9a, 0x07, 0x9f, 0xd9, 0x37, 0x96,
+  0x57, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x09, 0x75,
+  0x54, 0x4c, 0x71, 0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87,
+  0xe2, 0x96, 0xcb, 0x57, 0x99, 0xc4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x09, 0x75, 0x54, 0x4c, 0x71,
+  0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87, 0xe2, 0x96, 0xcb,
+  0x57, 0x99, 0xc4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x18, 0x8f, 0x0f, 0xbb, 0x2b, 0x58, 0xe1, 0x96,
+  0x9c, 0xd2, 0x9d, 0x38, 0x1e, 0x10, 0x1f, 0x98, 0x21, 0xb3, 0x13, 0x49,
+  0x47, 0x09, 0xd5, 0x4c, 0x97, 0x8f, 0xbb, 0x18, 0xd7, 0xe2, 0x8c, 0x0d,
+  0x67, 0x23, 0xf3, 0x3b, 0xfc, 0x7f, 0x7a, 0x42, 0xb5, 0x7d, 0xb4, 0x32,
+  0x10, 0xd4, 0xae, 0x42, 0x7f, 0xb8, 0x61, 0xbe, 0x82, 0x84, 0x7e, 0xa2,
+  0xed, 0xca, 0xd0, 0x0e, 0x1e, 0xa7, 0x6f, 0x74, 0xb3, 0xe7, 0xbe, 0x8e,
+  0xbd, 0x8d, 0x55, 0xcd, 0x4a, 0x3f, 0x2b, 0x14, 0x7c, 0xe4, 0x12, 0xf6,
+  0xb5, 0xcf, 0x80, 0xa5, 0xbc, 0x06, 0x27, 0xcd, 0xa1, 0x99, 0x90, 0x06,
+  0x16, 0x8f, 0x66, 0xe4, 0x2e, 0xb2, 0x5a, 0x00, 0xaf, 0xe5, 0x72, 0x4a,
+  0x7a, 0x7d, 0x81, 0xa5, 0x85, 0xe1, 0x65, 0x9f, 0xa0, 0xf8, 0x96, 0xda,
+  0x92, 0xbf, 0xa3, 0xce, 0xc6, 0xfc, 0x98, 0x0c, 0xe8, 0x54, 0x1a, 0x38,
+  0xd7, 0x6e, 0x95, 0x7d, 0x04, 0xe9, 0xc3, 0x26, 0x89, 0xfb, 0x3a, 0xe0,
+  0x2e, 0xae, 0x6a, 0xfe, 0xec, 0x6f, 0xe2, 0x6a, 0xcf, 0x6e, 0x67, 0x52,
+  0x3b, 0xb7, 0x11, 0xb4, 0x68, 0x77, 0xb5, 0x99, 0xe5, 0x01, 0x68, 0xbb,
+  0x94, 0xe2, 0x00, 0x12, 0x86, 0x92, 0x27, 0xa0, 0x8b, 0xbe, 0x1d, 0x62,
+  0xce, 0x7a, 0x1e, 0x6a, 0xa7, 0xfe, 0x28, 0x20, 0xfc, 0xd6, 0x99, 0xf5,
+  0xde, 0xd4, 0xd1, 0xc3, 0xfb, 0x3a, 0x04, 0x66, 0xa4, 0x1e, 0x77, 0x22,
+  0x0a, 0xa8, 0x53, 0xbd, 0x3d, 0x6a, 0x97, 0x88, 0x4e, 0x1f, 0x2e, 0xdd,
+  0x93, 0x08, 0x70, 0x80, 0xdc, 0x1a, 0xe2, 0x50, 0xb7, 0x04, 0x70, 0xa2,
+  0x3b, 0xaf, 0x7c, 0x4e, 0x5f, 0xf9, 0xa9, 0x40, 0x96, 0xce, 0xe4, 0xc4,
+  0x82, 0x69, 0x69, 0xc5, 0x24, 0xa8, 0xd8, 0x4c, 0xc1, 0x67, 0xa2, 0xfb,
+  0x09, 0x11, 0xb8, 0x81, 0xac, 0xd9, 0x67, 0x84, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x02, 0x14, 0x52, 0xe9, 0x66, 0x81,
+  0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82, 0x66, 0xd8, 0x3d, 0x2b,
+  0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x79, 0x52, 0xb9, 0x06, 0x98, 0x42, 0x91, 0x3e, 0x25, 0x19,
+  0xf1, 0xe9, 0x79, 0x32, 0x4f, 0x8e, 0x5e, 0x3a, 0xa4, 0xac, 0x7a, 0x0f,
+  0x8e, 0x8b, 0xcd, 0x98, 0xab, 0xe5, 0xac, 0x04, 0x41, 0xdc, 0x13, 0x2e,
+  0xdc, 0x19, 0x4f, 0x0e, 0xaa, 0xcf, 0x9d, 0xf3, 0x72, 0x09, 0x8a, 0x7c,
+  0x11, 0xd4, 0xd1, 0x6b, 0x42, 0x29, 0xc1, 0x4b, 0xea, 0x87, 0xda, 0xc0,
+  0xd2, 0x96, 0xa4, 0x41, 0x71, 0x6e, 0x07, 0xa8, 0x9f, 0x97, 0x5c, 0x06,
+  0x96, 0x31, 0xfe, 0x5b, 0xe0, 0x99, 0x89, 0xd4, 0x23, 0xdd, 0x9c, 0x78,
+  0x34, 0x0b, 0x33, 0xa1, 0x6a, 0xb1, 0xe9, 0xe7, 0x17, 0x93, 0xb2, 0x59,
+  0xd3, 0x72, 0xa6, 0xe2, 0xb7, 0xa2, 0x44, 0xac, 0x0b, 0xc9, 0x76, 0x84,
+  0x1f, 0xed, 0xdf, 0x9e, 0x32, 0x38, 0x04, 0x1a, 0x8b, 0x64, 0xdc, 0xcc,
+  0x97, 0x3b, 0xf2, 0x4d, 0xd2, 0xe4, 0x61, 0xe2, 0x65, 0xf7, 0xc9, 0x9b,
+  0xe9, 0xe7, 0xd0, 0xac, 0xf2, 0x6d, 0xbc, 0x89, 0x81, 0xea, 0xfe, 0x8f,
+  0x08, 0x3a, 0x68, 0xd8, 0xcd, 0xcd, 0x49, 0x63, 0x5b, 0x3c, 0x5a, 0x4f,
+  0x72, 0x48, 0x1d, 0x39, 0xca, 0x38, 0x1d, 0x12, 0x48, 0x73, 0x23, 0xad,
+  0x89, 0xe7, 0xcf, 0xa4, 0xf0, 0x39, 0xb7, 0x73, 0xab, 0x06, 0xa2, 0x61,
+  0xdc, 0x9d, 0xba, 0x4d, 0x68, 0x1f, 0xf2, 0x84, 0x03, 0x59, 0x31, 0xc3,
+  0x76, 0xae, 0x94, 0xd9, 0x0b, 0x0e, 0x8a, 0xaf, 0x5b, 0x8b, 0x83, 0xe8,
+  0x28, 0x06, 0x75, 0xb6, 0x51, 0xdc, 0x1a, 0xf2, 0xa0, 0x89, 0xfd, 0xea,
+  0x52, 0x7a, 0x6d, 0x85, 0x26, 0xc5, 0x56, 0x1e, 0x6e, 0xf9, 0xff, 0xa9,
+  0xa0, 0x04, 0x40, 0x33, 0x69, 0xb6, 0xc4, 0x5e, 0x7d, 0x00, 0x16, 0xd2,
+  0xd7, 0xe9, 0xc8, 0x48, 0x56, 0x46, 0x74, 0x47, 0x1d, 0xb7, 0x09, 0x94,
+  0xa2, 0xdb, 0xc7, 0xc2, 0x5f, 0x69
 };
-unsigned int KEK_delete_auth_len = 1225;
+unsigned int KEK_delete_auth_len = 1206;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/PK1.h b/components/service/uefi/smm_variable/test/service/auth_vectors/PK1.h
index fd8817a..9f5444b 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/PK1.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/PK1.h
@@ -7,176 +7,175 @@
  */
 
 unsigned char PK1_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0,
-  0x7a, 0xa6, 0xe6, 0x9b, 0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b,
-  0xc7, 0xa8, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
-  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xcb, 0x94, 0x4f, 0x33, 0x47, 0xe3, 0xb3,
-  0xd0, 0x34, 0x45, 0x48, 0xea, 0x6c, 0x66, 0x8d, 0xb0, 0x97, 0x41, 0xe8,
-  0x81, 0x7f, 0xab, 0x83, 0xa5, 0x9f, 0xa6, 0x5d, 0x47, 0x9b, 0x60, 0x55,
-  0xc3, 0x70, 0x2c, 0xf5, 0x96, 0x9f, 0xa8, 0xdb, 0xc0, 0xca, 0x63, 0x7c,
-  0x34, 0xed, 0x14, 0x9e, 0xc0, 0xbe, 0xab, 0xe4, 0x3b, 0x73, 0xed, 0x62,
-  0x24, 0xe8, 0x68, 0xa4, 0x14, 0x10, 0x50, 0x8f, 0x7f, 0x59, 0xad, 0xec,
-  0x16, 0x60, 0xfe, 0x1f, 0x60, 0x3b, 0x9a, 0x7b, 0x7a, 0xc3, 0x3e, 0xf4,
-  0xcf, 0x39, 0x27, 0x70, 0xb9, 0xd9, 0x0a, 0x40, 0xc7, 0x7f, 0x41, 0x80,
-  0xd3, 0xe0, 0x22, 0x15, 0x1a, 0x91, 0x0e, 0x4a, 0xa7, 0x52, 0x33, 0x72,
-  0xf2, 0x46, 0x03, 0x42, 0x36, 0x85, 0x27, 0xf0, 0x2f, 0x9f, 0x56, 0xa4,
-  0xd5, 0xdc, 0x00, 0xd5, 0x5e, 0xe5, 0x1a, 0x08, 0xae, 0xdc, 0x80, 0xb9,
-  0xa4, 0xcf, 0x58, 0xf1, 0xd4, 0x38, 0x5f, 0xe1, 0xff, 0x81, 0x01, 0xff,
-  0x17, 0x77, 0xe7, 0x4b, 0xee, 0x91, 0xaf, 0x3a, 0xf9, 0x73, 0xd9, 0x6f,
-  0xe9, 0x22, 0x55, 0x15, 0x17, 0xa9, 0xc9, 0xde, 0xfc, 0x63, 0xfc, 0x84,
-  0x96, 0xb7, 0xf8, 0x40, 0x63, 0x5f, 0x2c, 0x21, 0x20, 0x1e, 0x37, 0x14,
-  0x1b, 0x4e, 0x76, 0xec, 0x3a, 0xcb, 0xd5, 0xdc, 0xef, 0x96, 0x37, 0x43,
-  0x46, 0x4c, 0x2e, 0xf4, 0xcb, 0x58, 0x90, 0x91, 0x35, 0x6d, 0xb5, 0x58,
-  0xb8, 0xb7, 0x74, 0x72, 0x80, 0x3f, 0xb7, 0xd0, 0x1b, 0xca, 0x47, 0x18,
-  0xc9, 0x99, 0x4d, 0x74, 0x97, 0x57, 0xc4, 0x2f, 0x2e, 0x2a, 0xd0, 0x95,
-  0xc2, 0x1e, 0x64, 0x8d, 0xbd, 0xd1, 0x7e, 0xf6, 0x6c, 0x44, 0x01, 0x1f,
-  0x37, 0xc0, 0x67, 0x7a, 0x78, 0x47, 0x21, 0xb4, 0x0d, 0xc6, 0xab, 0x81,
-  0x7e, 0x1c, 0x10, 0x5d, 0x01, 0x2e, 0xfe, 0x41, 0x93, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4,
-  0xbb, 0x06, 0xa7, 0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66,
-  0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4, 0xbb, 0x06, 0xa7,
-  0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66, 0x08, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3a,
-  0xae, 0xa0, 0xfa, 0x34, 0x4a, 0x52, 0x24, 0x90, 0x3a, 0xba, 0x33, 0x61,
-  0x0f, 0xc8, 0x6f, 0xbc, 0x72, 0xf8, 0xc3, 0x98, 0x04, 0xe1, 0xcb, 0xf2,
-  0x82, 0xfd, 0x83, 0x59, 0x51, 0x23, 0x71, 0xf4, 0xce, 0xe9, 0x36, 0x4d,
-  0x0a, 0xd3, 0x11, 0x6d, 0x51, 0xb7, 0xd1, 0x9f, 0x9b, 0x85, 0x5c, 0x25,
-  0x11, 0x9c, 0x13, 0xf6, 0x33, 0xd8, 0xa4, 0x27, 0xef, 0x90, 0x56, 0x21,
-  0xe3, 0x90, 0x10, 0x2b, 0x50, 0x46, 0x6e, 0x8a, 0x84, 0x3e, 0x30, 0x4c,
-  0xc2, 0xdf, 0x81, 0x60, 0xdf, 0xb8, 0x06, 0xd8, 0x2f, 0xcf, 0x3f, 0xb8,
-  0xbe, 0x04, 0xa4, 0xbb, 0xba, 0x65, 0x9f, 0x4e, 0xc4, 0x05, 0xbe, 0x9e,
-  0xfe, 0xa9, 0x0c, 0x06, 0x81, 0xcc, 0xa4, 0x66, 0xb0, 0x14, 0x48, 0xc9,
-  0x24, 0x88, 0xd8, 0xdc, 0xf2, 0x5c, 0xb5, 0x59, 0x66, 0x4f, 0xc6, 0xa4,
-  0xa3, 0x96, 0xa8, 0x48, 0x3b, 0x43, 0xff, 0xe0, 0x10, 0x53, 0x79, 0x47,
-  0x74, 0xe8, 0xbc, 0xa9, 0x4f, 0x8e, 0x1f, 0xfb, 0xf8, 0xad, 0x8d, 0x10,
-  0x80, 0x8f, 0x80, 0xf8, 0x5b, 0x36, 0xff, 0x60, 0x0b, 0x3f, 0xb2, 0x2f,
-  0x46, 0x27, 0x43, 0x00, 0x1a, 0x0d, 0xb8, 0x91, 0x4e, 0x84, 0xb1, 0x94,
-  0xc2, 0xca, 0xd6, 0x36, 0x4d, 0xc6, 0xda, 0x53, 0x71, 0xcc, 0xc8, 0x8e,
-  0x9c, 0xdb, 0x31, 0xbb, 0x93, 0x49, 0xa7, 0xf4, 0x0b, 0x19, 0xcb, 0xaa,
-  0x2b, 0x0c, 0xf4, 0xc7, 0x59, 0x8a, 0xc6, 0x59, 0x0b, 0x1d, 0x2f, 0xc3,
-  0xcf, 0x06, 0xcf, 0x2e, 0x6b, 0x15, 0x6f, 0xba, 0xd1, 0xfa, 0x7d, 0x7f,
-  0xaa, 0x99, 0x09, 0x63, 0xa8, 0xdd, 0x6c, 0xdb, 0x6a, 0x5e, 0x00, 0x5e,
-  0x89, 0x11, 0xe3, 0xbd, 0xf6, 0xcb, 0x13, 0x89, 0x6a, 0xb8, 0x7e, 0x89,
-  0xbc, 0xa5, 0xec, 0x68, 0x85, 0xf0, 0xaa, 0x05, 0x91, 0xc1, 0x79, 0xa1,
-  0x1c, 0x9d, 0x32, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x31, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0, 0x7a, 0xa6, 0xe6, 0x9b,
-  0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b, 0xc7, 0xa8, 0x37, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x57, 0x48, 0xaf,
-  0x74, 0x8c, 0x31, 0x13, 0x78, 0x5a, 0x3f, 0x7f, 0xe2, 0xbb, 0x91, 0x66,
-  0x4a, 0xc7, 0x05, 0x87, 0xc5, 0x9c, 0x20, 0x11, 0xee, 0x1b, 0x1b, 0x7d,
-  0xcf, 0xe6, 0xb0, 0x90, 0xf5, 0x42, 0xdb, 0x78, 0x23, 0x96, 0x00, 0x34,
-  0xa9, 0x5e, 0xdf, 0x9c, 0xb2, 0x5c, 0xf6, 0xa3, 0xc1, 0xdf, 0x8b, 0x12,
-  0x5e, 0x34, 0x27, 0x5e, 0xdb, 0xab, 0xc5, 0x13, 0x66, 0x93, 0xdd, 0xec,
-  0x0e, 0x5d, 0xfe, 0x4c, 0x23, 0x3b, 0xbd, 0x94, 0x99, 0x88, 0x61, 0x05,
-  0x0b, 0xd2, 0xef, 0x18, 0xd2, 0xe1, 0xe7, 0x58, 0xff, 0x27, 0x1c, 0x3a,
-  0x66, 0x44, 0xe4, 0x24, 0xeb, 0x66, 0xc6, 0x8f, 0x38, 0x9f, 0x4e, 0xda,
-  0x96, 0xe4, 0xdb, 0x43, 0xb5, 0x13, 0xb9, 0xbe, 0xdc, 0xd4, 0x7a, 0xed,
-  0x6a, 0xcd, 0x98, 0x5d, 0x2b, 0x51, 0xb5, 0xd8, 0xe3, 0x10, 0xc9, 0x70,
-  0xa1, 0xaa, 0x68, 0x88, 0x21, 0x6f, 0x2e, 0x9c, 0xa8, 0x03, 0x7d, 0x22,
-  0x06, 0xa0, 0x24, 0x2b, 0x22, 0x55, 0x3f, 0x91, 0x44, 0xe5, 0x28, 0x39,
-  0x05, 0x2d, 0xa0, 0xe0, 0xcf, 0x85, 0xfa, 0xb6, 0x7d, 0x8f, 0x02, 0x7f,
-  0xd7, 0x42, 0xed, 0x07, 0xf7, 0xa0, 0xae, 0x61, 0x85, 0x40, 0x4b, 0xe5,
-  0x3e, 0x33, 0xc8, 0xeb, 0xb5, 0xed, 0x8f, 0x9a, 0xb7, 0xd5, 0x1b, 0xef,
-  0x86, 0x76, 0xe4, 0x7b, 0x61, 0x18, 0x5f, 0xac, 0xb0, 0x19, 0xc4, 0x45,
-  0x16, 0xd0, 0xed, 0xe2, 0x61, 0x61, 0xec, 0xca, 0xd1, 0x02, 0x0d, 0xbf,
-  0xba, 0x72, 0x0b, 0x45, 0xf9, 0xc3, 0xb0, 0xfd, 0x16, 0xd5, 0x2c, 0x32,
-  0xc1, 0x48, 0x2e, 0x9e, 0x7f, 0x62, 0x52, 0x39, 0x30, 0x3e, 0xbf, 0x55,
-  0xf9, 0xa5, 0x11, 0x9e, 0x12, 0xda, 0x20, 0x9b, 0x63, 0xad, 0xc3, 0x82,
-  0x49, 0x8d, 0x49, 0xa8, 0x22, 0x62, 0xc9, 0xac, 0x08, 0x81, 0x51, 0x98,
-  0xe1, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab,
-  0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x03,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
   0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
-  0x71, 0x90, 0xc6, 0x30, 0xd0, 0x7a, 0xa6, 0xe6, 0x9b, 0x3f, 0x3b, 0x01,
-  0x47, 0x16, 0xad, 0x20, 0x9b, 0xc7, 0xa8, 0x37, 0x30, 0x0d, 0x06, 0x09,
+  0x52, 0xe9, 0x66, 0x81, 0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82,
+  0x66, 0xd8, 0x3d, 0x2b, 0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
   0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d,
-  0x32, 0x34, 0x30, 0x31, 0x32, 0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38,
-  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32,
-  0x30, 0x30, 0x38, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x33, 0x39,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x33, 0x39, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
   0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
   0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
   0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
-  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xcb, 0x94,
-  0x4f, 0x33, 0x47, 0xe3, 0xb3, 0xd0, 0x34, 0x45, 0x48, 0xea, 0x6c, 0x66,
-  0x8d, 0xb0, 0x97, 0x41, 0xe8, 0x81, 0x7f, 0xab, 0x83, 0xa5, 0x9f, 0xa6,
-  0x5d, 0x47, 0x9b, 0x60, 0x55, 0xc3, 0x70, 0x2c, 0xf5, 0x96, 0x9f, 0xa8,
-  0xdb, 0xc0, 0xca, 0x63, 0x7c, 0x34, 0xed, 0x14, 0x9e, 0xc0, 0xbe, 0xab,
-  0xe4, 0x3b, 0x73, 0xed, 0x62, 0x24, 0xe8, 0x68, 0xa4, 0x14, 0x10, 0x50,
-  0x8f, 0x7f, 0x59, 0xad, 0xec, 0x16, 0x60, 0xfe, 0x1f, 0x60, 0x3b, 0x9a,
-  0x7b, 0x7a, 0xc3, 0x3e, 0xf4, 0xcf, 0x39, 0x27, 0x70, 0xb9, 0xd9, 0x0a,
-  0x40, 0xc7, 0x7f, 0x41, 0x80, 0xd3, 0xe0, 0x22, 0x15, 0x1a, 0x91, 0x0e,
-  0x4a, 0xa7, 0x52, 0x33, 0x72, 0xf2, 0x46, 0x03, 0x42, 0x36, 0x85, 0x27,
-  0xf0, 0x2f, 0x9f, 0x56, 0xa4, 0xd5, 0xdc, 0x00, 0xd5, 0x5e, 0xe5, 0x1a,
-  0x08, 0xae, 0xdc, 0x80, 0xb9, 0xa4, 0xcf, 0x58, 0xf1, 0xd4, 0x38, 0x5f,
-  0xe1, 0xff, 0x81, 0x01, 0xff, 0x17, 0x77, 0xe7, 0x4b, 0xee, 0x91, 0xaf,
-  0x3a, 0xf9, 0x73, 0xd9, 0x6f, 0xe9, 0x22, 0x55, 0x15, 0x17, 0xa9, 0xc9,
-  0xde, 0xfc, 0x63, 0xfc, 0x84, 0x96, 0xb7, 0xf8, 0x40, 0x63, 0x5f, 0x2c,
-  0x21, 0x20, 0x1e, 0x37, 0x14, 0x1b, 0x4e, 0x76, 0xec, 0x3a, 0xcb, 0xd5,
-  0xdc, 0xef, 0x96, 0x37, 0x43, 0x46, 0x4c, 0x2e, 0xf4, 0xcb, 0x58, 0x90,
-  0x91, 0x35, 0x6d, 0xb5, 0x58, 0xb8, 0xb7, 0x74, 0x72, 0x80, 0x3f, 0xb7,
-  0xd0, 0x1b, 0xca, 0x47, 0x18, 0xc9, 0x99, 0x4d, 0x74, 0x97, 0x57, 0xc4,
-  0x2f, 0x2e, 0x2a, 0xd0, 0x95, 0xc2, 0x1e, 0x64, 0x8d, 0xbd, 0xd1, 0x7e,
-  0xf6, 0x6c, 0x44, 0x01, 0x1f, 0x37, 0xc0, 0x67, 0x7a, 0x78, 0x47, 0x21,
-  0xb4, 0x0d, 0xc6, 0xab, 0x81, 0x7e, 0x1c, 0x10, 0x5d, 0x01, 0x2e, 0xfe,
-  0x41, 0x93, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
-  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x18, 0x51,
-  0xee, 0x40, 0x22, 0xae, 0xa4, 0xbb, 0x06, 0xa7, 0xf2, 0xb0, 0x08, 0xf9,
-  0x5e, 0x89, 0x08, 0x08, 0x66, 0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
-  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22,
-  0xae, 0xa4, 0xbb, 0x06, 0xa7, 0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08,
-  0x08, 0x66, 0x08, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb4, 0xbd,
+  0xd5, 0x2a, 0xdb, 0x3a, 0x4d, 0x37, 0x36, 0x4d, 0xbd, 0x2d, 0xdd, 0x31,
+  0xa0, 0x7c, 0x7b, 0x7e, 0xe9, 0x55, 0x50, 0x4b, 0xe5, 0x61, 0x69, 0x6e,
+  0x08, 0xe2, 0x82, 0x54, 0xfb, 0x00, 0xb6, 0x47, 0x01, 0x5c, 0x5b, 0x73,
+  0xa3, 0xde, 0x30, 0xa7, 0xd9, 0x8c, 0xeb, 0x4f, 0xda, 0x0a, 0x94, 0xc1,
+  0xd3, 0x97, 0x5c, 0xa7, 0x6f, 0x9e, 0xaa, 0xec, 0xa4, 0xf6, 0x8e, 0x73,
+  0x60, 0xe3, 0xac, 0xf7, 0x7e, 0x9b, 0x08, 0x30, 0x52, 0xff, 0x95, 0xb3,
+  0x7f, 0xf6, 0x6d, 0x5f, 0xa3, 0xcd, 0xa6, 0x56, 0x71, 0x33, 0xd0, 0xb4,
+  0xff, 0x03, 0x8c, 0xb2, 0x32, 0x91, 0x48, 0x85, 0x24, 0xd0, 0x68, 0x4c,
+  0xce, 0x62, 0xea, 0xca, 0xad, 0xa7, 0x72, 0x35, 0x14, 0xc3, 0x1d, 0x0a,
+  0x36, 0xb0, 0xd4, 0xcb, 0xd8, 0x0c, 0x98, 0xb9, 0x5f, 0x9b, 0xaa, 0x68,
+  0x27, 0xfc, 0xe2, 0xa0, 0x36, 0xee, 0xbc, 0x64, 0xfe, 0x8c, 0x50, 0xff,
+  0xb1, 0x4b, 0x68, 0xcb, 0x94, 0x38, 0x30, 0x9d, 0x67, 0x62, 0x55, 0x1e,
+  0x63, 0x79, 0x1b, 0xad, 0xd2, 0x5e, 0xb6, 0x5f, 0xb2, 0xc5, 0x0d, 0x9d,
+  0x4d, 0xc8, 0xa4, 0xfc, 0x83, 0x5e, 0x18, 0xee, 0xd1, 0xd7, 0x76, 0xe4,
+  0xb0, 0x2b, 0xd0, 0x2c, 0x17, 0xc9, 0x90, 0xe8, 0x80, 0x55, 0x57, 0xbb,
+  0x0a, 0x46, 0x21, 0x7e, 0x3b, 0x14, 0x77, 0xf0, 0xd8, 0x0c, 0x16, 0x37,
+  0x83, 0x8e, 0x1f, 0x4f, 0xaa, 0x00, 0x5c, 0x5d, 0x47, 0xd4, 0xcf, 0x73,
+  0x86, 0x3c, 0x58, 0x87, 0x82, 0xb1, 0x1d, 0x23, 0xac, 0x24, 0x76, 0xc8,
+  0xcb, 0xca, 0x4f, 0xd6, 0xf0, 0x8f, 0xcd, 0xa9, 0x63, 0xce, 0x57, 0x71,
+  0x88, 0xba, 0x20, 0x04, 0x94, 0x83, 0x87, 0x97, 0xc7, 0xd1, 0xdf, 0xc1,
+  0x1c, 0x07, 0x3f, 0x08, 0x53, 0x11, 0x9a, 0x07, 0x9f, 0xd9, 0x37, 0x96,
+  0x57, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x09, 0x75,
+  0x54, 0x4c, 0x71, 0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87,
+  0xe2, 0x96, 0xcb, 0x57, 0x99, 0xc4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x09, 0x75, 0x54, 0x4c, 0x71,
+  0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87, 0xe2, 0x96, 0xcb,
+  0x57, 0x99, 0xc4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
   0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
-  0x82, 0x01, 0x01, 0x00, 0x3a, 0xae, 0xa0, 0xfa, 0x34, 0x4a, 0x52, 0x24,
-  0x90, 0x3a, 0xba, 0x33, 0x61, 0x0f, 0xc8, 0x6f, 0xbc, 0x72, 0xf8, 0xc3,
-  0x98, 0x04, 0xe1, 0xcb, 0xf2, 0x82, 0xfd, 0x83, 0x59, 0x51, 0x23, 0x71,
-  0xf4, 0xce, 0xe9, 0x36, 0x4d, 0x0a, 0xd3, 0x11, 0x6d, 0x51, 0xb7, 0xd1,
-  0x9f, 0x9b, 0x85, 0x5c, 0x25, 0x11, 0x9c, 0x13, 0xf6, 0x33, 0xd8, 0xa4,
-  0x27, 0xef, 0x90, 0x56, 0x21, 0xe3, 0x90, 0x10, 0x2b, 0x50, 0x46, 0x6e,
-  0x8a, 0x84, 0x3e, 0x30, 0x4c, 0xc2, 0xdf, 0x81, 0x60, 0xdf, 0xb8, 0x06,
-  0xd8, 0x2f, 0xcf, 0x3f, 0xb8, 0xbe, 0x04, 0xa4, 0xbb, 0xba, 0x65, 0x9f,
-  0x4e, 0xc4, 0x05, 0xbe, 0x9e, 0xfe, 0xa9, 0x0c, 0x06, 0x81, 0xcc, 0xa4,
-  0x66, 0xb0, 0x14, 0x48, 0xc9, 0x24, 0x88, 0xd8, 0xdc, 0xf2, 0x5c, 0xb5,
-  0x59, 0x66, 0x4f, 0xc6, 0xa4, 0xa3, 0x96, 0xa8, 0x48, 0x3b, 0x43, 0xff,
-  0xe0, 0x10, 0x53, 0x79, 0x47, 0x74, 0xe8, 0xbc, 0xa9, 0x4f, 0x8e, 0x1f,
-  0xfb, 0xf8, 0xad, 0x8d, 0x10, 0x80, 0x8f, 0x80, 0xf8, 0x5b, 0x36, 0xff,
-  0x60, 0x0b, 0x3f, 0xb2, 0x2f, 0x46, 0x27, 0x43, 0x00, 0x1a, 0x0d, 0xb8,
-  0x91, 0x4e, 0x84, 0xb1, 0x94, 0xc2, 0xca, 0xd6, 0x36, 0x4d, 0xc6, 0xda,
-  0x53, 0x71, 0xcc, 0xc8, 0x8e, 0x9c, 0xdb, 0x31, 0xbb, 0x93, 0x49, 0xa7,
-  0xf4, 0x0b, 0x19, 0xcb, 0xaa, 0x2b, 0x0c, 0xf4, 0xc7, 0x59, 0x8a, 0xc6,
-  0x59, 0x0b, 0x1d, 0x2f, 0xc3, 0xcf, 0x06, 0xcf, 0x2e, 0x6b, 0x15, 0x6f,
-  0xba, 0xd1, 0xfa, 0x7d, 0x7f, 0xaa, 0x99, 0x09, 0x63, 0xa8, 0xdd, 0x6c,
-  0xdb, 0x6a, 0x5e, 0x00, 0x5e, 0x89, 0x11, 0xe3, 0xbd, 0xf6, 0xcb, 0x13,
-  0x89, 0x6a, 0xb8, 0x7e, 0x89, 0xbc, 0xa5, 0xec, 0x68, 0x85, 0xf0, 0xaa,
-  0x05, 0x91, 0xc1, 0x79, 0xa1, 0x1c, 0x9d, 0x32
+  0x82, 0x01, 0x01, 0x00, 0x18, 0x8f, 0x0f, 0xbb, 0x2b, 0x58, 0xe1, 0x96,
+  0x9c, 0xd2, 0x9d, 0x38, 0x1e, 0x10, 0x1f, 0x98, 0x21, 0xb3, 0x13, 0x49,
+  0x47, 0x09, 0xd5, 0x4c, 0x97, 0x8f, 0xbb, 0x18, 0xd7, 0xe2, 0x8c, 0x0d,
+  0x67, 0x23, 0xf3, 0x3b, 0xfc, 0x7f, 0x7a, 0x42, 0xb5, 0x7d, 0xb4, 0x32,
+  0x10, 0xd4, 0xae, 0x42, 0x7f, 0xb8, 0x61, 0xbe, 0x82, 0x84, 0x7e, 0xa2,
+  0xed, 0xca, 0xd0, 0x0e, 0x1e, 0xa7, 0x6f, 0x74, 0xb3, 0xe7, 0xbe, 0x8e,
+  0xbd, 0x8d, 0x55, 0xcd, 0x4a, 0x3f, 0x2b, 0x14, 0x7c, 0xe4, 0x12, 0xf6,
+  0xb5, 0xcf, 0x80, 0xa5, 0xbc, 0x06, 0x27, 0xcd, 0xa1, 0x99, 0x90, 0x06,
+  0x16, 0x8f, 0x66, 0xe4, 0x2e, 0xb2, 0x5a, 0x00, 0xaf, 0xe5, 0x72, 0x4a,
+  0x7a, 0x7d, 0x81, 0xa5, 0x85, 0xe1, 0x65, 0x9f, 0xa0, 0xf8, 0x96, 0xda,
+  0x92, 0xbf, 0xa3, 0xce, 0xc6, 0xfc, 0x98, 0x0c, 0xe8, 0x54, 0x1a, 0x38,
+  0xd7, 0x6e, 0x95, 0x7d, 0x04, 0xe9, 0xc3, 0x26, 0x89, 0xfb, 0x3a, 0xe0,
+  0x2e, 0xae, 0x6a, 0xfe, 0xec, 0x6f, 0xe2, 0x6a, 0xcf, 0x6e, 0x67, 0x52,
+  0x3b, 0xb7, 0x11, 0xb4, 0x68, 0x77, 0xb5, 0x99, 0xe5, 0x01, 0x68, 0xbb,
+  0x94, 0xe2, 0x00, 0x12, 0x86, 0x92, 0x27, 0xa0, 0x8b, 0xbe, 0x1d, 0x62,
+  0xce, 0x7a, 0x1e, 0x6a, 0xa7, 0xfe, 0x28, 0x20, 0xfc, 0xd6, 0x99, 0xf5,
+  0xde, 0xd4, 0xd1, 0xc3, 0xfb, 0x3a, 0x04, 0x66, 0xa4, 0x1e, 0x77, 0x22,
+  0x0a, 0xa8, 0x53, 0xbd, 0x3d, 0x6a, 0x97, 0x88, 0x4e, 0x1f, 0x2e, 0xdd,
+  0x93, 0x08, 0x70, 0x80, 0xdc, 0x1a, 0xe2, 0x50, 0xb7, 0x04, 0x70, 0xa2,
+  0x3b, 0xaf, 0x7c, 0x4e, 0x5f, 0xf9, 0xa9, 0x40, 0x96, 0xce, 0xe4, 0xc4,
+  0x82, 0x69, 0x69, 0xc5, 0x24, 0xa8, 0xd8, 0x4c, 0xc1, 0x67, 0xa2, 0xfb,
+  0x09, 0x11, 0xb8, 0x81, 0xac, 0xd9, 0x67, 0x84, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x02, 0x14, 0x52, 0xe9, 0x66, 0x81,
+  0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82, 0x66, 0xd8, 0x3d, 0x2b,
+  0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x44, 0x28, 0x14, 0xbb, 0x9c, 0xe7, 0x6f, 0xe3, 0x8b, 0x00,
+  0xf6, 0x79, 0x5c, 0x8b, 0xb6, 0x60, 0x21, 0x94, 0x2d, 0x47, 0xfa, 0xe5,
+  0xdb, 0x8d, 0x61, 0x88, 0xc7, 0x0f, 0x33, 0x3f, 0x32, 0xfa, 0xa5, 0x86,
+  0xd1, 0x97, 0x68, 0xe1, 0x7b, 0x80, 0x1a, 0xe6, 0x08, 0x50, 0xdc, 0xc7,
+  0x3a, 0xc9, 0x0e, 0xed, 0xd5, 0xef, 0xc7, 0x50, 0x4f, 0xc6, 0x8f, 0xc9,
+  0x80, 0x7d, 0xf5, 0x89, 0x7c, 0x47, 0x92, 0xa0, 0x85, 0x2a, 0xa1, 0xd9,
+  0x1d, 0x38, 0x3f, 0xbf, 0xb0, 0x34, 0x24, 0xed, 0x8b, 0x94, 0x71, 0x08,
+  0xb8, 0x42, 0xf9, 0xc4, 0x85, 0xe9, 0x49, 0x1b, 0xc5, 0xbc, 0xdf, 0x00,
+  0xc8, 0xa4, 0xc2, 0x65, 0x9d, 0x20, 0x93, 0x86, 0x6f, 0x3b, 0x8e, 0xb5,
+  0x5f, 0x3a, 0xd1, 0x14, 0x25, 0x7e, 0xb8, 0x0b, 0x08, 0x74, 0x41, 0x9d,
+  0x89, 0xa7, 0x10, 0x6d, 0x01, 0x90, 0xc5, 0x5f, 0x3d, 0xb8, 0x3f, 0x08,
+  0xed, 0x90, 0x17, 0x4d, 0xd0, 0x43, 0x67, 0x76, 0xbb, 0xe8, 0xb9, 0xea,
+  0xee, 0xfa, 0xcd, 0xe3, 0x6e, 0xff, 0x18, 0xbb, 0x05, 0x24, 0xcd, 0xeb,
+  0x32, 0x24, 0xbb, 0x9e, 0xfb, 0xf8, 0xa6, 0x23, 0x3f, 0xab, 0x99, 0x7c,
+  0x1c, 0xd0, 0xbb, 0x7f, 0x72, 0x1e, 0x55, 0x8d, 0x66, 0x87, 0xdb, 0xba,
+  0x5d, 0x66, 0xf7, 0x86, 0x8f, 0x44, 0x66, 0x1a, 0x62, 0x47, 0x5b, 0x44,
+  0x9c, 0x55, 0x09, 0x7f, 0xf4, 0xf7, 0x3f, 0x82, 0xbf, 0x21, 0x70, 0xa6,
+  0xdc, 0xbc, 0xf4, 0x9b, 0x8a, 0x70, 0x76, 0xab, 0x0f, 0xf9, 0x78, 0xbb,
+  0xe8, 0x80, 0x20, 0x7c, 0xa1, 0xb1, 0x2a, 0x54, 0xc1, 0x12, 0x24, 0x44,
+  0xd8, 0x84, 0x29, 0x7f, 0xf8, 0xc0, 0xad, 0x5d, 0xc1, 0x03, 0xae, 0xeb,
+  0xab, 0x60, 0x30, 0xee, 0x26, 0x5c, 0x8d, 0x12, 0x28, 0xf4, 0x83, 0xa3,
+  0xde, 0x10, 0x21, 0x3d, 0x96, 0xbe, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94,
+  0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03,
+  0x02, 0x01, 0x02, 0x02, 0x14, 0x52, 0xe9, 0x66, 0x81, 0x55, 0x20, 0x73,
+  0xd5, 0x35, 0x3f, 0xbd, 0x82, 0x66, 0xd8, 0x3d, 0x2b, 0x1a, 0x70, 0x67,
+  0x79, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
+  0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31,
+  0x30, 0x32, 0x31, 0x33, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36,
+  0x30, 0x39, 0x31, 0x30, 0x32, 0x31, 0x33, 0x39, 0x5a, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+  0x01, 0x01, 0x00, 0xb4, 0xbd, 0xd5, 0x2a, 0xdb, 0x3a, 0x4d, 0x37, 0x36,
+  0x4d, 0xbd, 0x2d, 0xdd, 0x31, 0xa0, 0x7c, 0x7b, 0x7e, 0xe9, 0x55, 0x50,
+  0x4b, 0xe5, 0x61, 0x69, 0x6e, 0x08, 0xe2, 0x82, 0x54, 0xfb, 0x00, 0xb6,
+  0x47, 0x01, 0x5c, 0x5b, 0x73, 0xa3, 0xde, 0x30, 0xa7, 0xd9, 0x8c, 0xeb,
+  0x4f, 0xda, 0x0a, 0x94, 0xc1, 0xd3, 0x97, 0x5c, 0xa7, 0x6f, 0x9e, 0xaa,
+  0xec, 0xa4, 0xf6, 0x8e, 0x73, 0x60, 0xe3, 0xac, 0xf7, 0x7e, 0x9b, 0x08,
+  0x30, 0x52, 0xff, 0x95, 0xb3, 0x7f, 0xf6, 0x6d, 0x5f, 0xa3, 0xcd, 0xa6,
+  0x56, 0x71, 0x33, 0xd0, 0xb4, 0xff, 0x03, 0x8c, 0xb2, 0x32, 0x91, 0x48,
+  0x85, 0x24, 0xd0, 0x68, 0x4c, 0xce, 0x62, 0xea, 0xca, 0xad, 0xa7, 0x72,
+  0x35, 0x14, 0xc3, 0x1d, 0x0a, 0x36, 0xb0, 0xd4, 0xcb, 0xd8, 0x0c, 0x98,
+  0xb9, 0x5f, 0x9b, 0xaa, 0x68, 0x27, 0xfc, 0xe2, 0xa0, 0x36, 0xee, 0xbc,
+  0x64, 0xfe, 0x8c, 0x50, 0xff, 0xb1, 0x4b, 0x68, 0xcb, 0x94, 0x38, 0x30,
+  0x9d, 0x67, 0x62, 0x55, 0x1e, 0x63, 0x79, 0x1b, 0xad, 0xd2, 0x5e, 0xb6,
+  0x5f, 0xb2, 0xc5, 0x0d, 0x9d, 0x4d, 0xc8, 0xa4, 0xfc, 0x83, 0x5e, 0x18,
+  0xee, 0xd1, 0xd7, 0x76, 0xe4, 0xb0, 0x2b, 0xd0, 0x2c, 0x17, 0xc9, 0x90,
+  0xe8, 0x80, 0x55, 0x57, 0xbb, 0x0a, 0x46, 0x21, 0x7e, 0x3b, 0x14, 0x77,
+  0xf0, 0xd8, 0x0c, 0x16, 0x37, 0x83, 0x8e, 0x1f, 0x4f, 0xaa, 0x00, 0x5c,
+  0x5d, 0x47, 0xd4, 0xcf, 0x73, 0x86, 0x3c, 0x58, 0x87, 0x82, 0xb1, 0x1d,
+  0x23, 0xac, 0x24, 0x76, 0xc8, 0xcb, 0xca, 0x4f, 0xd6, 0xf0, 0x8f, 0xcd,
+  0xa9, 0x63, 0xce, 0x57, 0x71, 0x88, 0xba, 0x20, 0x04, 0x94, 0x83, 0x87,
+  0x97, 0xc7, 0xd1, 0xdf, 0xc1, 0x1c, 0x07, 0x3f, 0x08, 0x53, 0x11, 0x9a,
+  0x07, 0x9f, 0xd9, 0x37, 0x96, 0x57, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x09, 0x75, 0x54, 0x4c, 0x71, 0xbc, 0xf2, 0x1e, 0x6b,
+  0x39, 0x31, 0xfe, 0xb7, 0x87, 0xe2, 0x96, 0xcb, 0x57, 0x99, 0xc4, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x09, 0x75, 0x54, 0x4c, 0x71, 0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe,
+  0xb7, 0x87, 0xe2, 0x96, 0xcb, 0x57, 0x99, 0xc4, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+  0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x18, 0x8f, 0x0f,
+  0xbb, 0x2b, 0x58, 0xe1, 0x96, 0x9c, 0xd2, 0x9d, 0x38, 0x1e, 0x10, 0x1f,
+  0x98, 0x21, 0xb3, 0x13, 0x49, 0x47, 0x09, 0xd5, 0x4c, 0x97, 0x8f, 0xbb,
+  0x18, 0xd7, 0xe2, 0x8c, 0x0d, 0x67, 0x23, 0xf3, 0x3b, 0xfc, 0x7f, 0x7a,
+  0x42, 0xb5, 0x7d, 0xb4, 0x32, 0x10, 0xd4, 0xae, 0x42, 0x7f, 0xb8, 0x61,
+  0xbe, 0x82, 0x84, 0x7e, 0xa2, 0xed, 0xca, 0xd0, 0x0e, 0x1e, 0xa7, 0x6f,
+  0x74, 0xb3, 0xe7, 0xbe, 0x8e, 0xbd, 0x8d, 0x55, 0xcd, 0x4a, 0x3f, 0x2b,
+  0x14, 0x7c, 0xe4, 0x12, 0xf6, 0xb5, 0xcf, 0x80, 0xa5, 0xbc, 0x06, 0x27,
+  0xcd, 0xa1, 0x99, 0x90, 0x06, 0x16, 0x8f, 0x66, 0xe4, 0x2e, 0xb2, 0x5a,
+  0x00, 0xaf, 0xe5, 0x72, 0x4a, 0x7a, 0x7d, 0x81, 0xa5, 0x85, 0xe1, 0x65,
+  0x9f, 0xa0, 0xf8, 0x96, 0xda, 0x92, 0xbf, 0xa3, 0xce, 0xc6, 0xfc, 0x98,
+  0x0c, 0xe8, 0x54, 0x1a, 0x38, 0xd7, 0x6e, 0x95, 0x7d, 0x04, 0xe9, 0xc3,
+  0x26, 0x89, 0xfb, 0x3a, 0xe0, 0x2e, 0xae, 0x6a, 0xfe, 0xec, 0x6f, 0xe2,
+  0x6a, 0xcf, 0x6e, 0x67, 0x52, 0x3b, 0xb7, 0x11, 0xb4, 0x68, 0x77, 0xb5,
+  0x99, 0xe5, 0x01, 0x68, 0xbb, 0x94, 0xe2, 0x00, 0x12, 0x86, 0x92, 0x27,
+  0xa0, 0x8b, 0xbe, 0x1d, 0x62, 0xce, 0x7a, 0x1e, 0x6a, 0xa7, 0xfe, 0x28,
+  0x20, 0xfc, 0xd6, 0x99, 0xf5, 0xde, 0xd4, 0xd1, 0xc3, 0xfb, 0x3a, 0x04,
+  0x66, 0xa4, 0x1e, 0x77, 0x22, 0x0a, 0xa8, 0x53, 0xbd, 0x3d, 0x6a, 0x97,
+  0x88, 0x4e, 0x1f, 0x2e, 0xdd, 0x93, 0x08, 0x70, 0x80, 0xdc, 0x1a, 0xe2,
+  0x50, 0xb7, 0x04, 0x70, 0xa2, 0x3b, 0xaf, 0x7c, 0x4e, 0x5f, 0xf9, 0xa9,
+  0x40, 0x96, 0xce, 0xe4, 0xc4, 0x82, 0x69, 0x69, 0xc5, 0x24, 0xa8, 0xd8,
+  0x4c, 0xc1, 0x67, 0xa2, 0xfb, 0x09, 0x11, 0xb8, 0x81, 0xac, 0xd9, 0x67,
+  0x84
 };
-unsigned int PK1_auth_len = 2048;
+unsigned int PK1_auth_len = 2029;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/PK1_delete.h b/components/service/uefi/smm_variable/test/service/auth_vectors/PK1_delete.h
index e6c3992..cec3552 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/PK1_delete.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/PK1_delete.h
@@ -7,108 +7,106 @@
  */
 
 unsigned char PK1_delete_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0,
-  0x7a, 0xa6, 0xe6, 0x9b, 0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b,
-  0xc7, 0xa8, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x52, 0xe9, 0x66, 0x81, 0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82,
+  0x66, 0xd8, 0x3d, 0x2b, 0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xcb, 0x94, 0x4f, 0x33, 0x47, 0xe3, 0xb3,
-  0xd0, 0x34, 0x45, 0x48, 0xea, 0x6c, 0x66, 0x8d, 0xb0, 0x97, 0x41, 0xe8,
-  0x81, 0x7f, 0xab, 0x83, 0xa5, 0x9f, 0xa6, 0x5d, 0x47, 0x9b, 0x60, 0x55,
-  0xc3, 0x70, 0x2c, 0xf5, 0x96, 0x9f, 0xa8, 0xdb, 0xc0, 0xca, 0x63, 0x7c,
-  0x34, 0xed, 0x14, 0x9e, 0xc0, 0xbe, 0xab, 0xe4, 0x3b, 0x73, 0xed, 0x62,
-  0x24, 0xe8, 0x68, 0xa4, 0x14, 0x10, 0x50, 0x8f, 0x7f, 0x59, 0xad, 0xec,
-  0x16, 0x60, 0xfe, 0x1f, 0x60, 0x3b, 0x9a, 0x7b, 0x7a, 0xc3, 0x3e, 0xf4,
-  0xcf, 0x39, 0x27, 0x70, 0xb9, 0xd9, 0x0a, 0x40, 0xc7, 0x7f, 0x41, 0x80,
-  0xd3, 0xe0, 0x22, 0x15, 0x1a, 0x91, 0x0e, 0x4a, 0xa7, 0x52, 0x33, 0x72,
-  0xf2, 0x46, 0x03, 0x42, 0x36, 0x85, 0x27, 0xf0, 0x2f, 0x9f, 0x56, 0xa4,
-  0xd5, 0xdc, 0x00, 0xd5, 0x5e, 0xe5, 0x1a, 0x08, 0xae, 0xdc, 0x80, 0xb9,
-  0xa4, 0xcf, 0x58, 0xf1, 0xd4, 0x38, 0x5f, 0xe1, 0xff, 0x81, 0x01, 0xff,
-  0x17, 0x77, 0xe7, 0x4b, 0xee, 0x91, 0xaf, 0x3a, 0xf9, 0x73, 0xd9, 0x6f,
-  0xe9, 0x22, 0x55, 0x15, 0x17, 0xa9, 0xc9, 0xde, 0xfc, 0x63, 0xfc, 0x84,
-  0x96, 0xb7, 0xf8, 0x40, 0x63, 0x5f, 0x2c, 0x21, 0x20, 0x1e, 0x37, 0x14,
-  0x1b, 0x4e, 0x76, 0xec, 0x3a, 0xcb, 0xd5, 0xdc, 0xef, 0x96, 0x37, 0x43,
-  0x46, 0x4c, 0x2e, 0xf4, 0xcb, 0x58, 0x90, 0x91, 0x35, 0x6d, 0xb5, 0x58,
-  0xb8, 0xb7, 0x74, 0x72, 0x80, 0x3f, 0xb7, 0xd0, 0x1b, 0xca, 0x47, 0x18,
-  0xc9, 0x99, 0x4d, 0x74, 0x97, 0x57, 0xc4, 0x2f, 0x2e, 0x2a, 0xd0, 0x95,
-  0xc2, 0x1e, 0x64, 0x8d, 0xbd, 0xd1, 0x7e, 0xf6, 0x6c, 0x44, 0x01, 0x1f,
-  0x37, 0xc0, 0x67, 0x7a, 0x78, 0x47, 0x21, 0xb4, 0x0d, 0xc6, 0xab, 0x81,
-  0x7e, 0x1c, 0x10, 0x5d, 0x01, 0x2e, 0xfe, 0x41, 0x93, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4,
-  0xbb, 0x06, 0xa7, 0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66,
-  0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4, 0xbb, 0x06, 0xa7,
-  0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66, 0x08, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3a,
-  0xae, 0xa0, 0xfa, 0x34, 0x4a, 0x52, 0x24, 0x90, 0x3a, 0xba, 0x33, 0x61,
-  0x0f, 0xc8, 0x6f, 0xbc, 0x72, 0xf8, 0xc3, 0x98, 0x04, 0xe1, 0xcb, 0xf2,
-  0x82, 0xfd, 0x83, 0x59, 0x51, 0x23, 0x71, 0xf4, 0xce, 0xe9, 0x36, 0x4d,
-  0x0a, 0xd3, 0x11, 0x6d, 0x51, 0xb7, 0xd1, 0x9f, 0x9b, 0x85, 0x5c, 0x25,
-  0x11, 0x9c, 0x13, 0xf6, 0x33, 0xd8, 0xa4, 0x27, 0xef, 0x90, 0x56, 0x21,
-  0xe3, 0x90, 0x10, 0x2b, 0x50, 0x46, 0x6e, 0x8a, 0x84, 0x3e, 0x30, 0x4c,
-  0xc2, 0xdf, 0x81, 0x60, 0xdf, 0xb8, 0x06, 0xd8, 0x2f, 0xcf, 0x3f, 0xb8,
-  0xbe, 0x04, 0xa4, 0xbb, 0xba, 0x65, 0x9f, 0x4e, 0xc4, 0x05, 0xbe, 0x9e,
-  0xfe, 0xa9, 0x0c, 0x06, 0x81, 0xcc, 0xa4, 0x66, 0xb0, 0x14, 0x48, 0xc9,
-  0x24, 0x88, 0xd8, 0xdc, 0xf2, 0x5c, 0xb5, 0x59, 0x66, 0x4f, 0xc6, 0xa4,
-  0xa3, 0x96, 0xa8, 0x48, 0x3b, 0x43, 0xff, 0xe0, 0x10, 0x53, 0x79, 0x47,
-  0x74, 0xe8, 0xbc, 0xa9, 0x4f, 0x8e, 0x1f, 0xfb, 0xf8, 0xad, 0x8d, 0x10,
-  0x80, 0x8f, 0x80, 0xf8, 0x5b, 0x36, 0xff, 0x60, 0x0b, 0x3f, 0xb2, 0x2f,
-  0x46, 0x27, 0x43, 0x00, 0x1a, 0x0d, 0xb8, 0x91, 0x4e, 0x84, 0xb1, 0x94,
-  0xc2, 0xca, 0xd6, 0x36, 0x4d, 0xc6, 0xda, 0x53, 0x71, 0xcc, 0xc8, 0x8e,
-  0x9c, 0xdb, 0x31, 0xbb, 0x93, 0x49, 0xa7, 0xf4, 0x0b, 0x19, 0xcb, 0xaa,
-  0x2b, 0x0c, 0xf4, 0xc7, 0x59, 0x8a, 0xc6, 0x59, 0x0b, 0x1d, 0x2f, 0xc3,
-  0xcf, 0x06, 0xcf, 0x2e, 0x6b, 0x15, 0x6f, 0xba, 0xd1, 0xfa, 0x7d, 0x7f,
-  0xaa, 0x99, 0x09, 0x63, 0xa8, 0xdd, 0x6c, 0xdb, 0x6a, 0x5e, 0x00, 0x5e,
-  0x89, 0x11, 0xe3, 0xbd, 0xf6, 0xcb, 0x13, 0x89, 0x6a, 0xb8, 0x7e, 0x89,
-  0xbc, 0xa5, 0xec, 0x68, 0x85, 0xf0, 0xaa, 0x05, 0x91, 0xc1, 0x79, 0xa1,
-  0x1c, 0x9d, 0x32, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x33, 0x39,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x33, 0x39, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
   0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x31, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0, 0x7a, 0xa6, 0xe6, 0x9b,
-  0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b, 0xc7, 0xa8, 0x37, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xaf, 0x30, 0x48,
-  0x00, 0x6c, 0x9a, 0xa0, 0x99, 0xb3, 0x46, 0x88, 0xa5, 0x59, 0x23, 0x2e,
-  0x60, 0x5f, 0x2d, 0xda, 0x31, 0x3a, 0x34, 0x96, 0x2e, 0xd3, 0xe0, 0x07,
-  0xaa, 0x5f, 0x31, 0x8c, 0xa6, 0xa8, 0x09, 0x30, 0x1e, 0x9b, 0xad, 0x39,
-  0xff, 0x13, 0x7e, 0x01, 0x82, 0x79, 0xb4, 0x91, 0xea, 0x73, 0x6d, 0x61,
-  0x98, 0x1f, 0xb6, 0x4a, 0xf6, 0x88, 0x78, 0xaf, 0xad, 0x5b, 0x15, 0xb4,
-  0x12, 0x41, 0x45, 0x70, 0xb5, 0xf5, 0x07, 0xf9, 0x8a, 0x68, 0xd0, 0xfc,
-  0xcc, 0x4d, 0x2a, 0x78, 0x54, 0x38, 0xa3, 0x38, 0x85, 0xa9, 0x25, 0x38,
-  0xb4, 0xb0, 0xcd, 0x4e, 0x04, 0xc6, 0x5c, 0xb6, 0x15, 0x86, 0x35, 0xb8,
-  0x30, 0x8b, 0x43, 0x4a, 0x06, 0xde, 0x4d, 0x4f, 0xc5, 0x8a, 0x63, 0xd7,
-  0x2d, 0x31, 0xf2, 0x4d, 0x59, 0xf7, 0x74, 0xdd, 0x33, 0x6e, 0x3d, 0x9a,
-  0xe6, 0xc5, 0x51, 0xc0, 0x64, 0x89, 0x4e, 0x64, 0xaa, 0x6b, 0xf0, 0x35,
-  0x91, 0xf5, 0x16, 0x04, 0xee, 0xc4, 0xd9, 0x97, 0x38, 0x55, 0x5a, 0x4b,
-  0x1b, 0x17, 0x91, 0x6b, 0x28, 0xd6, 0xa5, 0xb6, 0xc4, 0x9b, 0xc7, 0xfe,
-  0x5d, 0x1d, 0xa2, 0x5e, 0xb2, 0x1d, 0xf3, 0x50, 0x2b, 0x45, 0x3f, 0xdd,
-  0xbc, 0x2e, 0x8a, 0xa2, 0x04, 0x03, 0xcf, 0xbf, 0xf5, 0x59, 0x0a, 0xbf,
-  0x5b, 0x76, 0xe3, 0x2a, 0x34, 0x26, 0x0c, 0x74, 0x88, 0xfe, 0x2a, 0x07,
-  0x95, 0x82, 0x05, 0x37, 0x8c, 0xe4, 0xd6, 0x90, 0x21, 0x22, 0xdc, 0xc0,
-  0x35, 0xea, 0xc4, 0xd6, 0x8b, 0xe2, 0xdc, 0x95, 0xe0, 0x12, 0x51, 0xf9,
-  0xbe, 0x1d, 0xb6, 0x93, 0x7f, 0x34, 0x02, 0xc7, 0x1d, 0x14, 0x27, 0xd1,
-  0xf3, 0x15, 0x63, 0x95, 0x48, 0x20, 0x9a, 0xcf, 0x56, 0x83, 0x0c, 0x8d,
-  0xce, 0xf9, 0x86, 0x00, 0x0a, 0xad, 0xfe, 0x3c, 0xd2, 0x14, 0xd4, 0xd2,
-  0x18
+  0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb4, 0xbd,
+  0xd5, 0x2a, 0xdb, 0x3a, 0x4d, 0x37, 0x36, 0x4d, 0xbd, 0x2d, 0xdd, 0x31,
+  0xa0, 0x7c, 0x7b, 0x7e, 0xe9, 0x55, 0x50, 0x4b, 0xe5, 0x61, 0x69, 0x6e,
+  0x08, 0xe2, 0x82, 0x54, 0xfb, 0x00, 0xb6, 0x47, 0x01, 0x5c, 0x5b, 0x73,
+  0xa3, 0xde, 0x30, 0xa7, 0xd9, 0x8c, 0xeb, 0x4f, 0xda, 0x0a, 0x94, 0xc1,
+  0xd3, 0x97, 0x5c, 0xa7, 0x6f, 0x9e, 0xaa, 0xec, 0xa4, 0xf6, 0x8e, 0x73,
+  0x60, 0xe3, 0xac, 0xf7, 0x7e, 0x9b, 0x08, 0x30, 0x52, 0xff, 0x95, 0xb3,
+  0x7f, 0xf6, 0x6d, 0x5f, 0xa3, 0xcd, 0xa6, 0x56, 0x71, 0x33, 0xd0, 0xb4,
+  0xff, 0x03, 0x8c, 0xb2, 0x32, 0x91, 0x48, 0x85, 0x24, 0xd0, 0x68, 0x4c,
+  0xce, 0x62, 0xea, 0xca, 0xad, 0xa7, 0x72, 0x35, 0x14, 0xc3, 0x1d, 0x0a,
+  0x36, 0xb0, 0xd4, 0xcb, 0xd8, 0x0c, 0x98, 0xb9, 0x5f, 0x9b, 0xaa, 0x68,
+  0x27, 0xfc, 0xe2, 0xa0, 0x36, 0xee, 0xbc, 0x64, 0xfe, 0x8c, 0x50, 0xff,
+  0xb1, 0x4b, 0x68, 0xcb, 0x94, 0x38, 0x30, 0x9d, 0x67, 0x62, 0x55, 0x1e,
+  0x63, 0x79, 0x1b, 0xad, 0xd2, 0x5e, 0xb6, 0x5f, 0xb2, 0xc5, 0x0d, 0x9d,
+  0x4d, 0xc8, 0xa4, 0xfc, 0x83, 0x5e, 0x18, 0xee, 0xd1, 0xd7, 0x76, 0xe4,
+  0xb0, 0x2b, 0xd0, 0x2c, 0x17, 0xc9, 0x90, 0xe8, 0x80, 0x55, 0x57, 0xbb,
+  0x0a, 0x46, 0x21, 0x7e, 0x3b, 0x14, 0x77, 0xf0, 0xd8, 0x0c, 0x16, 0x37,
+  0x83, 0x8e, 0x1f, 0x4f, 0xaa, 0x00, 0x5c, 0x5d, 0x47, 0xd4, 0xcf, 0x73,
+  0x86, 0x3c, 0x58, 0x87, 0x82, 0xb1, 0x1d, 0x23, 0xac, 0x24, 0x76, 0xc8,
+  0xcb, 0xca, 0x4f, 0xd6, 0xf0, 0x8f, 0xcd, 0xa9, 0x63, 0xce, 0x57, 0x71,
+  0x88, 0xba, 0x20, 0x04, 0x94, 0x83, 0x87, 0x97, 0xc7, 0xd1, 0xdf, 0xc1,
+  0x1c, 0x07, 0x3f, 0x08, 0x53, 0x11, 0x9a, 0x07, 0x9f, 0xd9, 0x37, 0x96,
+  0x57, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x09, 0x75,
+  0x54, 0x4c, 0x71, 0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87,
+  0xe2, 0x96, 0xcb, 0x57, 0x99, 0xc4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x09, 0x75, 0x54, 0x4c, 0x71,
+  0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87, 0xe2, 0x96, 0xcb,
+  0x57, 0x99, 0xc4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x18, 0x8f, 0x0f, 0xbb, 0x2b, 0x58, 0xe1, 0x96,
+  0x9c, 0xd2, 0x9d, 0x38, 0x1e, 0x10, 0x1f, 0x98, 0x21, 0xb3, 0x13, 0x49,
+  0x47, 0x09, 0xd5, 0x4c, 0x97, 0x8f, 0xbb, 0x18, 0xd7, 0xe2, 0x8c, 0x0d,
+  0x67, 0x23, 0xf3, 0x3b, 0xfc, 0x7f, 0x7a, 0x42, 0xb5, 0x7d, 0xb4, 0x32,
+  0x10, 0xd4, 0xae, 0x42, 0x7f, 0xb8, 0x61, 0xbe, 0x82, 0x84, 0x7e, 0xa2,
+  0xed, 0xca, 0xd0, 0x0e, 0x1e, 0xa7, 0x6f, 0x74, 0xb3, 0xe7, 0xbe, 0x8e,
+  0xbd, 0x8d, 0x55, 0xcd, 0x4a, 0x3f, 0x2b, 0x14, 0x7c, 0xe4, 0x12, 0xf6,
+  0xb5, 0xcf, 0x80, 0xa5, 0xbc, 0x06, 0x27, 0xcd, 0xa1, 0x99, 0x90, 0x06,
+  0x16, 0x8f, 0x66, 0xe4, 0x2e, 0xb2, 0x5a, 0x00, 0xaf, 0xe5, 0x72, 0x4a,
+  0x7a, 0x7d, 0x81, 0xa5, 0x85, 0xe1, 0x65, 0x9f, 0xa0, 0xf8, 0x96, 0xda,
+  0x92, 0xbf, 0xa3, 0xce, 0xc6, 0xfc, 0x98, 0x0c, 0xe8, 0x54, 0x1a, 0x38,
+  0xd7, 0x6e, 0x95, 0x7d, 0x04, 0xe9, 0xc3, 0x26, 0x89, 0xfb, 0x3a, 0xe0,
+  0x2e, 0xae, 0x6a, 0xfe, 0xec, 0x6f, 0xe2, 0x6a, 0xcf, 0x6e, 0x67, 0x52,
+  0x3b, 0xb7, 0x11, 0xb4, 0x68, 0x77, 0xb5, 0x99, 0xe5, 0x01, 0x68, 0xbb,
+  0x94, 0xe2, 0x00, 0x12, 0x86, 0x92, 0x27, 0xa0, 0x8b, 0xbe, 0x1d, 0x62,
+  0xce, 0x7a, 0x1e, 0x6a, 0xa7, 0xfe, 0x28, 0x20, 0xfc, 0xd6, 0x99, 0xf5,
+  0xde, 0xd4, 0xd1, 0xc3, 0xfb, 0x3a, 0x04, 0x66, 0xa4, 0x1e, 0x77, 0x22,
+  0x0a, 0xa8, 0x53, 0xbd, 0x3d, 0x6a, 0x97, 0x88, 0x4e, 0x1f, 0x2e, 0xdd,
+  0x93, 0x08, 0x70, 0x80, 0xdc, 0x1a, 0xe2, 0x50, 0xb7, 0x04, 0x70, 0xa2,
+  0x3b, 0xaf, 0x7c, 0x4e, 0x5f, 0xf9, 0xa9, 0x40, 0x96, 0xce, 0xe4, 0xc4,
+  0x82, 0x69, 0x69, 0xc5, 0x24, 0xa8, 0xd8, 0x4c, 0xc1, 0x67, 0xa2, 0xfb,
+  0x09, 0x11, 0xb8, 0x81, 0xac, 0xd9, 0x67, 0x84, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x02, 0x14, 0x52, 0xe9, 0x66, 0x81,
+  0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82, 0x66, 0xd8, 0x3d, 0x2b,
+  0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0xa4, 0xff, 0x7b, 0xb4, 0x0b, 0x62, 0xcb, 0x23, 0xbd, 0xa1,
+  0x2a, 0xa9, 0xbe, 0x81, 0xc4, 0xf1, 0x1f, 0x33, 0xfb, 0x82, 0x89, 0x94,
+  0x4f, 0x38, 0xef, 0x16, 0xc1, 0xc0, 0x2b, 0x6d, 0x41, 0xd1, 0xb9, 0xe6,
+  0x71, 0xb1, 0xbc, 0x90, 0x90, 0x67, 0xf2, 0x33, 0x1c, 0x96, 0xfd, 0xd6,
+  0xf6, 0xaa, 0xd4, 0x81, 0x86, 0x4c, 0xc3, 0x5a, 0xbf, 0xf4, 0xbc, 0x99,
+  0x0b, 0xe0, 0x16, 0x50, 0xd6, 0x9a, 0x27, 0x8e, 0x79, 0x79, 0xdc, 0xe8,
+  0xdb, 0x64, 0xd6, 0x51, 0xab, 0x2c, 0xa3, 0xa7, 0x50, 0x2a, 0x18, 0xb5,
+  0xfd, 0x1b, 0xe1, 0x36, 0xff, 0xe1, 0x0e, 0x88, 0x42, 0x58, 0xba, 0x0c,
+  0x67, 0xc6, 0x30, 0xf7, 0x70, 0xee, 0x01, 0x64, 0x6f, 0x33, 0x5a, 0x7e,
+  0x4d, 0x30, 0x9b, 0x87, 0xc4, 0xbe, 0xd1, 0xe1, 0x89, 0x9e, 0xec, 0x1e,
+  0xf1, 0x1e, 0x47, 0xa4, 0x8c, 0xd7, 0xdb, 0xc0, 0x84, 0x57, 0xce, 0xd7,
+  0x1b, 0xf0, 0xe7, 0xb6, 0x27, 0xe0, 0x1d, 0xb6, 0xe0, 0x5b, 0x87, 0x6f,
+  0xe0, 0x0f, 0x0d, 0xff, 0x49, 0x65, 0xf3, 0x88, 0x9b, 0x63, 0x11, 0xeb,
+  0x21, 0xf7, 0xd7, 0x95, 0x62, 0xb2, 0x72, 0xc1, 0x9f, 0xe0, 0xfd, 0xc5,
+  0x80, 0x9b, 0xb2, 0x32, 0x52, 0x5c, 0xee, 0x9b, 0x31, 0x6a, 0x56, 0xc7,
+  0xd2, 0xd7, 0x20, 0x06, 0x16, 0x16, 0x9b, 0x5b, 0xea, 0x25, 0x24, 0x06,
+  0x2e, 0x8a, 0x87, 0x19, 0xe2, 0x1d, 0x42, 0xcf, 0x11, 0x97, 0x12, 0xfe,
+  0xdb, 0xa3, 0xdd, 0x57, 0xcd, 0x63, 0x88, 0xad, 0xc0, 0x71, 0x8e, 0xde,
+  0xad, 0x18, 0xbf, 0xf0, 0x2a, 0xcb, 0x66, 0x26, 0x15, 0x1b, 0x0c, 0xe6,
+  0x20, 0x5e, 0x43, 0x6d, 0x87, 0x29, 0x41, 0xaa, 0x60, 0x88, 0xa3, 0x79,
+  0x05, 0xba, 0xdf, 0x39, 0x02, 0xb9, 0x9a, 0xc0, 0xc0, 0x17, 0x6f, 0x5a,
+  0x17, 0x1a, 0x2b, 0xc6, 0xc1, 0xcc
 };
-unsigned int PK1_delete_auth_len = 1225;
+unsigned int PK1_delete_auth_len = 1206;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/PK2.h b/components/service/uefi/smm_variable/test/service/auth_vectors/PK2.h
index 3ca9f1c..4e90842 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/PK2.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/PK2.h
@@ -7,176 +7,175 @@
  */
 
 unsigned char PK2_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0,
-  0x7a, 0xa6, 0xe6, 0x9b, 0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b,
-  0xc7, 0xa8, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
-  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xcb, 0x94, 0x4f, 0x33, 0x47, 0xe3, 0xb3,
-  0xd0, 0x34, 0x45, 0x48, 0xea, 0x6c, 0x66, 0x8d, 0xb0, 0x97, 0x41, 0xe8,
-  0x81, 0x7f, 0xab, 0x83, 0xa5, 0x9f, 0xa6, 0x5d, 0x47, 0x9b, 0x60, 0x55,
-  0xc3, 0x70, 0x2c, 0xf5, 0x96, 0x9f, 0xa8, 0xdb, 0xc0, 0xca, 0x63, 0x7c,
-  0x34, 0xed, 0x14, 0x9e, 0xc0, 0xbe, 0xab, 0xe4, 0x3b, 0x73, 0xed, 0x62,
-  0x24, 0xe8, 0x68, 0xa4, 0x14, 0x10, 0x50, 0x8f, 0x7f, 0x59, 0xad, 0xec,
-  0x16, 0x60, 0xfe, 0x1f, 0x60, 0x3b, 0x9a, 0x7b, 0x7a, 0xc3, 0x3e, 0xf4,
-  0xcf, 0x39, 0x27, 0x70, 0xb9, 0xd9, 0x0a, 0x40, 0xc7, 0x7f, 0x41, 0x80,
-  0xd3, 0xe0, 0x22, 0x15, 0x1a, 0x91, 0x0e, 0x4a, 0xa7, 0x52, 0x33, 0x72,
-  0xf2, 0x46, 0x03, 0x42, 0x36, 0x85, 0x27, 0xf0, 0x2f, 0x9f, 0x56, 0xa4,
-  0xd5, 0xdc, 0x00, 0xd5, 0x5e, 0xe5, 0x1a, 0x08, 0xae, 0xdc, 0x80, 0xb9,
-  0xa4, 0xcf, 0x58, 0xf1, 0xd4, 0x38, 0x5f, 0xe1, 0xff, 0x81, 0x01, 0xff,
-  0x17, 0x77, 0xe7, 0x4b, 0xee, 0x91, 0xaf, 0x3a, 0xf9, 0x73, 0xd9, 0x6f,
-  0xe9, 0x22, 0x55, 0x15, 0x17, 0xa9, 0xc9, 0xde, 0xfc, 0x63, 0xfc, 0x84,
-  0x96, 0xb7, 0xf8, 0x40, 0x63, 0x5f, 0x2c, 0x21, 0x20, 0x1e, 0x37, 0x14,
-  0x1b, 0x4e, 0x76, 0xec, 0x3a, 0xcb, 0xd5, 0xdc, 0xef, 0x96, 0x37, 0x43,
-  0x46, 0x4c, 0x2e, 0xf4, 0xcb, 0x58, 0x90, 0x91, 0x35, 0x6d, 0xb5, 0x58,
-  0xb8, 0xb7, 0x74, 0x72, 0x80, 0x3f, 0xb7, 0xd0, 0x1b, 0xca, 0x47, 0x18,
-  0xc9, 0x99, 0x4d, 0x74, 0x97, 0x57, 0xc4, 0x2f, 0x2e, 0x2a, 0xd0, 0x95,
-  0xc2, 0x1e, 0x64, 0x8d, 0xbd, 0xd1, 0x7e, 0xf6, 0x6c, 0x44, 0x01, 0x1f,
-  0x37, 0xc0, 0x67, 0x7a, 0x78, 0x47, 0x21, 0xb4, 0x0d, 0xc6, 0xab, 0x81,
-  0x7e, 0x1c, 0x10, 0x5d, 0x01, 0x2e, 0xfe, 0x41, 0x93, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4,
-  0xbb, 0x06, 0xa7, 0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66,
-  0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4, 0xbb, 0x06, 0xa7,
-  0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66, 0x08, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3a,
-  0xae, 0xa0, 0xfa, 0x34, 0x4a, 0x52, 0x24, 0x90, 0x3a, 0xba, 0x33, 0x61,
-  0x0f, 0xc8, 0x6f, 0xbc, 0x72, 0xf8, 0xc3, 0x98, 0x04, 0xe1, 0xcb, 0xf2,
-  0x82, 0xfd, 0x83, 0x59, 0x51, 0x23, 0x71, 0xf4, 0xce, 0xe9, 0x36, 0x4d,
-  0x0a, 0xd3, 0x11, 0x6d, 0x51, 0xb7, 0xd1, 0x9f, 0x9b, 0x85, 0x5c, 0x25,
-  0x11, 0x9c, 0x13, 0xf6, 0x33, 0xd8, 0xa4, 0x27, 0xef, 0x90, 0x56, 0x21,
-  0xe3, 0x90, 0x10, 0x2b, 0x50, 0x46, 0x6e, 0x8a, 0x84, 0x3e, 0x30, 0x4c,
-  0xc2, 0xdf, 0x81, 0x60, 0xdf, 0xb8, 0x06, 0xd8, 0x2f, 0xcf, 0x3f, 0xb8,
-  0xbe, 0x04, 0xa4, 0xbb, 0xba, 0x65, 0x9f, 0x4e, 0xc4, 0x05, 0xbe, 0x9e,
-  0xfe, 0xa9, 0x0c, 0x06, 0x81, 0xcc, 0xa4, 0x66, 0xb0, 0x14, 0x48, 0xc9,
-  0x24, 0x88, 0xd8, 0xdc, 0xf2, 0x5c, 0xb5, 0x59, 0x66, 0x4f, 0xc6, 0xa4,
-  0xa3, 0x96, 0xa8, 0x48, 0x3b, 0x43, 0xff, 0xe0, 0x10, 0x53, 0x79, 0x47,
-  0x74, 0xe8, 0xbc, 0xa9, 0x4f, 0x8e, 0x1f, 0xfb, 0xf8, 0xad, 0x8d, 0x10,
-  0x80, 0x8f, 0x80, 0xf8, 0x5b, 0x36, 0xff, 0x60, 0x0b, 0x3f, 0xb2, 0x2f,
-  0x46, 0x27, 0x43, 0x00, 0x1a, 0x0d, 0xb8, 0x91, 0x4e, 0x84, 0xb1, 0x94,
-  0xc2, 0xca, 0xd6, 0x36, 0x4d, 0xc6, 0xda, 0x53, 0x71, 0xcc, 0xc8, 0x8e,
-  0x9c, 0xdb, 0x31, 0xbb, 0x93, 0x49, 0xa7, 0xf4, 0x0b, 0x19, 0xcb, 0xaa,
-  0x2b, 0x0c, 0xf4, 0xc7, 0x59, 0x8a, 0xc6, 0x59, 0x0b, 0x1d, 0x2f, 0xc3,
-  0xcf, 0x06, 0xcf, 0x2e, 0x6b, 0x15, 0x6f, 0xba, 0xd1, 0xfa, 0x7d, 0x7f,
-  0xaa, 0x99, 0x09, 0x63, 0xa8, 0xdd, 0x6c, 0xdb, 0x6a, 0x5e, 0x00, 0x5e,
-  0x89, 0x11, 0xe3, 0xbd, 0xf6, 0xcb, 0x13, 0x89, 0x6a, 0xb8, 0x7e, 0x89,
-  0xbc, 0xa5, 0xec, 0x68, 0x85, 0xf0, 0xaa, 0x05, 0x91, 0xc1, 0x79, 0xa1,
-  0x1c, 0x9d, 0x32, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x31, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0, 0x7a, 0xa6, 0xe6, 0x9b,
-  0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b, 0xc7, 0xa8, 0x37, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xb8, 0xf2, 0x58,
-  0x9f, 0x1b, 0x92, 0x17, 0x4f, 0x47, 0x0e, 0x55, 0x76, 0xdf, 0x6d, 0xdd,
-  0x45, 0xba, 0x59, 0x0f, 0x60, 0x33, 0xee, 0x5a, 0x79, 0x5d, 0x52, 0x4b,
-  0xcf, 0xd2, 0x37, 0x3c, 0x5d, 0xfd, 0x05, 0x16, 0x3d, 0xc7, 0x71, 0x15,
-  0xde, 0xa9, 0x87, 0x67, 0x31, 0xef, 0x9a, 0xea, 0xce, 0x3f, 0x15, 0xc2,
-  0x5c, 0xd3, 0xd2, 0x95, 0x63, 0xb5, 0xfe, 0x61, 0xd6, 0x53, 0x9f, 0x16,
-  0xee, 0x28, 0xf1, 0xbc, 0xe9, 0x68, 0xc4, 0x3e, 0x72, 0x55, 0x2b, 0x8b,
-  0x14, 0x86, 0x2f, 0x5f, 0x43, 0xda, 0x2b, 0x9b, 0x1b, 0x8e, 0x62, 0x33,
-  0x7a, 0x7c, 0x3a, 0x00, 0x60, 0x7a, 0x25, 0x8b, 0x0e, 0x52, 0x09, 0x5a,
-  0x9e, 0x65, 0x45, 0x2d, 0xd8, 0xb1, 0xae, 0x53, 0xc8, 0xdb, 0x39, 0xd9,
-  0xe3, 0x3e, 0xa5, 0xb6, 0x9e, 0xa1, 0xdb, 0x8e, 0xc8, 0x7b, 0x27, 0x47,
-  0xe5, 0x4a, 0x15, 0x57, 0x1b, 0x6d, 0xa3, 0xbb, 0x32, 0x66, 0xb7, 0x35,
-  0x14, 0x27, 0xb2, 0xa3, 0x8d, 0xad, 0xb2, 0xe9, 0x1b, 0x79, 0x8a, 0x88,
-  0xb6, 0x63, 0x9a, 0xa4, 0x59, 0xac, 0xa7, 0xe1, 0x6b, 0x4b, 0xb0, 0x18,
-  0x79, 0xca, 0x3d, 0x9b, 0x90, 0x3d, 0x7c, 0x3a, 0xa5, 0x4c, 0xa8, 0x5c,
-  0x32, 0xae, 0xad, 0x8b, 0xe9, 0x65, 0x06, 0x1b, 0x3a, 0xa5, 0xaa, 0x5c,
-  0x3f, 0x3c, 0xb5, 0x05, 0x23, 0x8e, 0xae, 0x86, 0xdf, 0x84, 0x11, 0xf2,
-  0x3f, 0xee, 0xa9, 0xd6, 0xd1, 0x07, 0x01, 0xd9, 0x8c, 0xe2, 0x0a, 0xbd,
-  0x7b, 0x56, 0x5d, 0x10, 0xd2, 0x37, 0x53, 0x27, 0xf9, 0xbf, 0xcd, 0xfa,
-  0x8d, 0x13, 0x30, 0x0b, 0xd8, 0x4d, 0x58, 0xee, 0x00, 0xd0, 0x2e, 0x0d,
-  0x6a, 0xee, 0x8f, 0x1b, 0xcd, 0x04, 0x20, 0x74, 0xf6, 0x5d, 0x88, 0xaf,
-  0xd8, 0x7b, 0xf2, 0x8a, 0xd6, 0x95, 0xa6, 0x4a, 0xc9, 0x61, 0xf2, 0xac,
-  0x8e, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab,
-  0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x03,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
   0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
-  0x54, 0xb4, 0x06, 0x14, 0xf0, 0x9e, 0x6a, 0xc1, 0xcf, 0x44, 0x44, 0xef,
-  0x02, 0xf5, 0x79, 0x50, 0xf9, 0xaf, 0xf7, 0xe1, 0x30, 0x0d, 0x06, 0x09,
+  0x52, 0xe9, 0x66, 0x81, 0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82,
+  0x66, 0xd8, 0x3d, 0x2b, 0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x32, 0x30, 0x1e, 0x17, 0x0d,
-  0x32, 0x34, 0x30, 0x31, 0x32, 0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38,
-  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32,
-  0x30, 0x30, 0x38, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x33, 0x39,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x33, 0x39, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
   0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
   0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
-  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x98,
-  0xcb, 0x8b, 0xd4, 0x05, 0x9b, 0x8d, 0x45, 0x0d, 0xed, 0xe5, 0x32, 0x38,
-  0x51, 0x41, 0xb1, 0xc6, 0x46, 0x30, 0x8d, 0xdf, 0x7d, 0xb3, 0xf9, 0x2f,
-  0x4b, 0x87, 0x55, 0xcc, 0xb0, 0x10, 0xa0, 0xbd, 0x43, 0x9c, 0x09, 0x1e,
-  0x7b, 0xa8, 0x50, 0x24, 0x87, 0x39, 0x8f, 0x3e, 0xb9, 0x33, 0x63, 0x3b,
-  0xd3, 0x8a, 0x08, 0x1b, 0x8f, 0xee, 0x11, 0x5b, 0x2b, 0x8a, 0xc2, 0xe1,
-  0x1e, 0x20, 0xf8, 0x41, 0x84, 0xc3, 0xea, 0x30, 0xaf, 0x36, 0x35, 0x6d,
-  0xfe, 0x78, 0x66, 0x32, 0xdf, 0xe4, 0x13, 0xaa, 0x3a, 0xe7, 0x78, 0xc0,
-  0x54, 0xc8, 0x8a, 0x05, 0xa3, 0x4a, 0x37, 0xc8, 0x09, 0xa8, 0x33, 0x5c,
-  0xb7, 0xa5, 0x6c, 0x61, 0x70, 0x36, 0x47, 0xae, 0xc9, 0xaf, 0xcb, 0x01,
-  0x85, 0x1e, 0x1f, 0x23, 0x9d, 0x1c, 0xc7, 0x42, 0xf0, 0x34, 0xe9, 0xb2,
-  0x73, 0xa0, 0x74, 0x2a, 0x87, 0xc2, 0xdb, 0xef, 0x3a, 0xa3, 0xca, 0x20,
-  0x42, 0xec, 0xd3, 0x62, 0x47, 0x79, 0x74, 0x7c, 0xa2, 0x72, 0x37, 0x11,
-  0x99, 0xff, 0x07, 0x28, 0x5e, 0xc7, 0x25, 0x08, 0x69, 0xa0, 0x66, 0x95,
-  0x8b, 0x0f, 0x89, 0x09, 0x4c, 0x99, 0x7d, 0x4f, 0xd5, 0x8c, 0xe2, 0xc6,
-  0x54, 0xa4, 0x7e, 0xd2, 0xc8, 0x63, 0x2a, 0x6f, 0xe1, 0x86, 0x44, 0x27,
-  0x16, 0x29, 0x06, 0x1f, 0x1d, 0x73, 0xfc, 0x9f, 0x7e, 0xf3, 0xbb, 0xae,
-  0xb1, 0x77, 0x54, 0x2f, 0x62, 0xd2, 0x79, 0xd2, 0x38, 0x6d, 0x60, 0x68,
-  0x3c, 0xbe, 0xae, 0x71, 0xb2, 0x7c, 0x06, 0x45, 0x6f, 0x5e, 0x5a, 0x44,
-  0x36, 0x4f, 0xf9, 0x5d, 0x4e, 0xe7, 0xaf, 0xde, 0x54, 0x3a, 0x0d, 0xb7,
-  0x19, 0x96, 0xad, 0x5e, 0x99, 0xac, 0x80, 0x24, 0x2d, 0x74, 0x1f, 0x35,
-  0xf9, 0xed, 0x30, 0x1e, 0xdc, 0x8b, 0x32, 0xcd, 0x25, 0xe4, 0x28, 0x27,
-  0x03, 0x05, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
-  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x87, 0x5a,
-  0x48, 0x88, 0x29, 0xf1, 0x9c, 0xfe, 0xfa, 0xde, 0xd7, 0xd8, 0xd9, 0x55,
-  0xd7, 0x22, 0x5d, 0xc2, 0x7f, 0x35, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
-  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x87, 0x5a, 0x48, 0x88, 0x29,
-  0xf1, 0x9c, 0xfe, 0xfa, 0xde, 0xd7, 0xd8, 0xd9, 0x55, 0xd7, 0x22, 0x5d,
-  0xc2, 0x7f, 0x35, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb4, 0xbd,
+  0xd5, 0x2a, 0xdb, 0x3a, 0x4d, 0x37, 0x36, 0x4d, 0xbd, 0x2d, 0xdd, 0x31,
+  0xa0, 0x7c, 0x7b, 0x7e, 0xe9, 0x55, 0x50, 0x4b, 0xe5, 0x61, 0x69, 0x6e,
+  0x08, 0xe2, 0x82, 0x54, 0xfb, 0x00, 0xb6, 0x47, 0x01, 0x5c, 0x5b, 0x73,
+  0xa3, 0xde, 0x30, 0xa7, 0xd9, 0x8c, 0xeb, 0x4f, 0xda, 0x0a, 0x94, 0xc1,
+  0xd3, 0x97, 0x5c, 0xa7, 0x6f, 0x9e, 0xaa, 0xec, 0xa4, 0xf6, 0x8e, 0x73,
+  0x60, 0xe3, 0xac, 0xf7, 0x7e, 0x9b, 0x08, 0x30, 0x52, 0xff, 0x95, 0xb3,
+  0x7f, 0xf6, 0x6d, 0x5f, 0xa3, 0xcd, 0xa6, 0x56, 0x71, 0x33, 0xd0, 0xb4,
+  0xff, 0x03, 0x8c, 0xb2, 0x32, 0x91, 0x48, 0x85, 0x24, 0xd0, 0x68, 0x4c,
+  0xce, 0x62, 0xea, 0xca, 0xad, 0xa7, 0x72, 0x35, 0x14, 0xc3, 0x1d, 0x0a,
+  0x36, 0xb0, 0xd4, 0xcb, 0xd8, 0x0c, 0x98, 0xb9, 0x5f, 0x9b, 0xaa, 0x68,
+  0x27, 0xfc, 0xe2, 0xa0, 0x36, 0xee, 0xbc, 0x64, 0xfe, 0x8c, 0x50, 0xff,
+  0xb1, 0x4b, 0x68, 0xcb, 0x94, 0x38, 0x30, 0x9d, 0x67, 0x62, 0x55, 0x1e,
+  0x63, 0x79, 0x1b, 0xad, 0xd2, 0x5e, 0xb6, 0x5f, 0xb2, 0xc5, 0x0d, 0x9d,
+  0x4d, 0xc8, 0xa4, 0xfc, 0x83, 0x5e, 0x18, 0xee, 0xd1, 0xd7, 0x76, 0xe4,
+  0xb0, 0x2b, 0xd0, 0x2c, 0x17, 0xc9, 0x90, 0xe8, 0x80, 0x55, 0x57, 0xbb,
+  0x0a, 0x46, 0x21, 0x7e, 0x3b, 0x14, 0x77, 0xf0, 0xd8, 0x0c, 0x16, 0x37,
+  0x83, 0x8e, 0x1f, 0x4f, 0xaa, 0x00, 0x5c, 0x5d, 0x47, 0xd4, 0xcf, 0x73,
+  0x86, 0x3c, 0x58, 0x87, 0x82, 0xb1, 0x1d, 0x23, 0xac, 0x24, 0x76, 0xc8,
+  0xcb, 0xca, 0x4f, 0xd6, 0xf0, 0x8f, 0xcd, 0xa9, 0x63, 0xce, 0x57, 0x71,
+  0x88, 0xba, 0x20, 0x04, 0x94, 0x83, 0x87, 0x97, 0xc7, 0xd1, 0xdf, 0xc1,
+  0x1c, 0x07, 0x3f, 0x08, 0x53, 0x11, 0x9a, 0x07, 0x9f, 0xd9, 0x37, 0x96,
+  0x57, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x09, 0x75,
+  0x54, 0x4c, 0x71, 0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87,
+  0xe2, 0x96, 0xcb, 0x57, 0x99, 0xc4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x09, 0x75, 0x54, 0x4c, 0x71,
+  0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87, 0xe2, 0x96, 0xcb,
+  0x57, 0x99, 0xc4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
   0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
-  0x82, 0x01, 0x01, 0x00, 0xac, 0xa0, 0x15, 0xab, 0xce, 0x98, 0xaa, 0x61,
-  0x6d, 0x3c, 0x84, 0xfa, 0x10, 0xed, 0xa8, 0x59, 0x32, 0x00, 0x37, 0x80,
-  0x96, 0xb8, 0x51, 0x0a, 0xd8, 0xae, 0x74, 0x4e, 0x47, 0x8a, 0x8d, 0x1b,
-  0xc6, 0xeb, 0x06, 0x58, 0xcd, 0x02, 0x73, 0xf7, 0x33, 0x6c, 0x5c, 0x7a,
-  0x69, 0xd5, 0x65, 0xf3, 0x85, 0xe8, 0x3f, 0x91, 0x3a, 0xd4, 0x7c, 0x36,
-  0x9a, 0xa8, 0xbb, 0xec, 0x74, 0x41, 0x7d, 0xd3, 0x40, 0xe4, 0x78, 0x2d,
-  0x36, 0x29, 0xfa, 0x58, 0x2e, 0xbc, 0x56, 0x40, 0x44, 0x32, 0xc6, 0x51,
-  0x85, 0xc2, 0x24, 0xb0, 0xaa, 0x0b, 0x3c, 0x06, 0x95, 0xb3, 0x6d, 0x68,
-  0x91, 0x99, 0x86, 0xe9, 0xb2, 0xba, 0x7d, 0x28, 0xdd, 0x2d, 0x67, 0x3c,
-  0x8c, 0x85, 0xaa, 0x6c, 0x94, 0xd4, 0xae, 0xfd, 0x6a, 0xaa, 0xf9, 0x53,
-  0x04, 0xe6, 0x13, 0x4a, 0x7b, 0x2c, 0x94, 0x10, 0x41, 0x74, 0x2a, 0x41,
-  0xdd, 0x10, 0xfc, 0x86, 0x23, 0x62, 0xf2, 0x9a, 0xb6, 0x41, 0xc5, 0xbd,
-  0x4f, 0xaa, 0xd5, 0xcc, 0x74, 0x9c, 0xf7, 0x3b, 0x31, 0x9a, 0xda, 0xf2,
-  0x20, 0x5d, 0x8a, 0x1e, 0xe3, 0xff, 0xd8, 0x7e, 0xa3, 0x2e, 0x8f, 0x5a,
-  0x30, 0x68, 0x85, 0xd6, 0x9f, 0xf1, 0xbd, 0x6a, 0x49, 0x64, 0x93, 0x2d,
-  0xb0, 0x5e, 0x68, 0x44, 0xb6, 0xfe, 0x64, 0x19, 0x75, 0x72, 0x49, 0x14,
-  0x32, 0xff, 0x0a, 0x2b, 0x15, 0x3f, 0xb4, 0x98, 0x69, 0xee, 0x1e, 0xbf,
-  0x0e, 0x14, 0x18, 0xe4, 0xc7, 0x78, 0x6d, 0x39, 0x5a, 0xfc, 0x41, 0x8b,
-  0x23, 0x42, 0xf2, 0x9f, 0x7d, 0x18, 0xee, 0x23, 0x6e, 0x67, 0x9f, 0xe9,
-  0x38, 0x51, 0x14, 0x67, 0xca, 0x5c, 0x75, 0xc9, 0xf3, 0x8c, 0xaa, 0x68,
-  0x2a, 0x28, 0xd5, 0xa4, 0x07, 0xbb, 0xe9, 0x5b, 0xf2, 0xde, 0x74, 0x13,
-  0x08, 0x6c, 0x8f, 0x31, 0x3a, 0x52, 0x08, 0x56
+  0x82, 0x01, 0x01, 0x00, 0x18, 0x8f, 0x0f, 0xbb, 0x2b, 0x58, 0xe1, 0x96,
+  0x9c, 0xd2, 0x9d, 0x38, 0x1e, 0x10, 0x1f, 0x98, 0x21, 0xb3, 0x13, 0x49,
+  0x47, 0x09, 0xd5, 0x4c, 0x97, 0x8f, 0xbb, 0x18, 0xd7, 0xe2, 0x8c, 0x0d,
+  0x67, 0x23, 0xf3, 0x3b, 0xfc, 0x7f, 0x7a, 0x42, 0xb5, 0x7d, 0xb4, 0x32,
+  0x10, 0xd4, 0xae, 0x42, 0x7f, 0xb8, 0x61, 0xbe, 0x82, 0x84, 0x7e, 0xa2,
+  0xed, 0xca, 0xd0, 0x0e, 0x1e, 0xa7, 0x6f, 0x74, 0xb3, 0xe7, 0xbe, 0x8e,
+  0xbd, 0x8d, 0x55, 0xcd, 0x4a, 0x3f, 0x2b, 0x14, 0x7c, 0xe4, 0x12, 0xf6,
+  0xb5, 0xcf, 0x80, 0xa5, 0xbc, 0x06, 0x27, 0xcd, 0xa1, 0x99, 0x90, 0x06,
+  0x16, 0x8f, 0x66, 0xe4, 0x2e, 0xb2, 0x5a, 0x00, 0xaf, 0xe5, 0x72, 0x4a,
+  0x7a, 0x7d, 0x81, 0xa5, 0x85, 0xe1, 0x65, 0x9f, 0xa0, 0xf8, 0x96, 0xda,
+  0x92, 0xbf, 0xa3, 0xce, 0xc6, 0xfc, 0x98, 0x0c, 0xe8, 0x54, 0x1a, 0x38,
+  0xd7, 0x6e, 0x95, 0x7d, 0x04, 0xe9, 0xc3, 0x26, 0x89, 0xfb, 0x3a, 0xe0,
+  0x2e, 0xae, 0x6a, 0xfe, 0xec, 0x6f, 0xe2, 0x6a, 0xcf, 0x6e, 0x67, 0x52,
+  0x3b, 0xb7, 0x11, 0xb4, 0x68, 0x77, 0xb5, 0x99, 0xe5, 0x01, 0x68, 0xbb,
+  0x94, 0xe2, 0x00, 0x12, 0x86, 0x92, 0x27, 0xa0, 0x8b, 0xbe, 0x1d, 0x62,
+  0xce, 0x7a, 0x1e, 0x6a, 0xa7, 0xfe, 0x28, 0x20, 0xfc, 0xd6, 0x99, 0xf5,
+  0xde, 0xd4, 0xd1, 0xc3, 0xfb, 0x3a, 0x04, 0x66, 0xa4, 0x1e, 0x77, 0x22,
+  0x0a, 0xa8, 0x53, 0xbd, 0x3d, 0x6a, 0x97, 0x88, 0x4e, 0x1f, 0x2e, 0xdd,
+  0x93, 0x08, 0x70, 0x80, 0xdc, 0x1a, 0xe2, 0x50, 0xb7, 0x04, 0x70, 0xa2,
+  0x3b, 0xaf, 0x7c, 0x4e, 0x5f, 0xf9, 0xa9, 0x40, 0x96, 0xce, 0xe4, 0xc4,
+  0x82, 0x69, 0x69, 0xc5, 0x24, 0xa8, 0xd8, 0x4c, 0xc1, 0x67, 0xa2, 0xfb,
+  0x09, 0x11, 0xb8, 0x81, 0xac, 0xd9, 0x67, 0x84, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x02, 0x14, 0x52, 0xe9, 0x66, 0x81,
+  0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82, 0x66, 0xd8, 0x3d, 0x2b,
+  0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x86, 0xe7, 0xd3, 0xf2, 0xcc, 0x93, 0xcb, 0x0d, 0x76, 0xf7,
+  0xa9, 0x22, 0x9f, 0xd6, 0x32, 0x9f, 0x48, 0x56, 0x67, 0x17, 0xaa, 0x1d,
+  0x48, 0xe5, 0x16, 0xa9, 0x5c, 0x0a, 0x63, 0x60, 0xcd, 0x4a, 0x9e, 0xd0,
+  0x6d, 0x5d, 0x95, 0x11, 0x7b, 0x0d, 0x5c, 0x5a, 0x09, 0xe4, 0x2c, 0x3d,
+  0xc4, 0xed, 0xeb, 0x41, 0x5e, 0x1d, 0xb7, 0x59, 0x03, 0x6b, 0x24, 0xde,
+  0x0f, 0x20, 0x8d, 0xc5, 0x21, 0x4f, 0x95, 0x2a, 0x5c, 0x52, 0xda, 0xd4,
+  0x95, 0x17, 0x6a, 0x8d, 0xe0, 0xb8, 0x7b, 0x2b, 0x6a, 0xc3, 0xb1, 0x8e,
+  0x89, 0xbd, 0x37, 0x38, 0xd1, 0x2b, 0x45, 0x0e, 0x51, 0xd2, 0xc8, 0xd8,
+  0xb2, 0x7f, 0xc3, 0xdb, 0xc5, 0xee, 0x99, 0xdb, 0xcb, 0xcb, 0xef, 0x93,
+  0x88, 0x6b, 0x5d, 0xf0, 0xf1, 0x47, 0xff, 0x90, 0xd2, 0x9c, 0x76, 0xa6,
+  0x92, 0x04, 0x1f, 0x58, 0x87, 0xf4, 0xbf, 0x5a, 0xb8, 0x49, 0x59, 0x31,
+  0x53, 0x0d, 0xf2, 0xd1, 0x2f, 0x47, 0xd9, 0x12, 0x21, 0x6b, 0x57, 0x74,
+  0xcd, 0x27, 0x95, 0x4a, 0xea, 0x06, 0x8e, 0xe5, 0x19, 0xdd, 0x29, 0xf4,
+  0x4b, 0x42, 0x26, 0xbc, 0x2b, 0xd0, 0x09, 0x3a, 0xc7, 0xed, 0x50, 0x3b,
+  0xc0, 0xb7, 0x69, 0xd6, 0x1d, 0xc4, 0xc1, 0xa3, 0xa7, 0xd0, 0x84, 0xb7,
+  0xf2, 0x16, 0x9d, 0x91, 0xf5, 0xe8, 0x25, 0x39, 0x98, 0x16, 0xad, 0xce,
+  0xfd, 0x6a, 0xb5, 0x38, 0x3e, 0xd7, 0xb6, 0x8b, 0x24, 0xb1, 0xc8, 0x66,
+  0x1b, 0x86, 0xfd, 0xbc, 0xff, 0xff, 0xa2, 0xe2, 0x6e, 0xb1, 0xd9, 0xbc,
+  0x5e, 0xae, 0x8d, 0x6a, 0x96, 0x56, 0x23, 0x39, 0x3c, 0x18, 0x5d, 0xb1,
+  0x17, 0x3d, 0x03, 0xa0, 0x92, 0x84, 0x37, 0x76, 0xb6, 0x38, 0x3f, 0x8d,
+  0x1b, 0xb2, 0xd3, 0x78, 0x9f, 0x8a, 0x2e, 0xf9, 0x78, 0x56, 0x58, 0xb1,
+  0x9a, 0xc3, 0xb7, 0xf2, 0xf3, 0xf0, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94,
+  0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03,
+  0x02, 0x01, 0x02, 0x02, 0x14, 0x60, 0x17, 0xf8, 0x61, 0x5d, 0x4e, 0x91,
+  0x73, 0xe3, 0xd4, 0x5c, 0xb9, 0x2d, 0xbb, 0xd0, 0xd8, 0xdc, 0x46, 0x23,
+  0x21, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
+  0x32, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31,
+  0x30, 0x32, 0x31, 0x34, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36,
+  0x30, 0x39, 0x31, 0x30, 0x32, 0x31, 0x34, 0x32, 0x5a, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+  0x01, 0x01, 0x00, 0xba, 0x07, 0x56, 0x02, 0x70, 0xff, 0xc9, 0xc6, 0xc6,
+  0x8e, 0xf6, 0xf8, 0x6c, 0x99, 0xbf, 0x1f, 0x4d, 0x6e, 0x23, 0xc8, 0x85,
+  0xaf, 0x81, 0x37, 0xa1, 0x45, 0xe2, 0x42, 0x8e, 0x73, 0x7b, 0x6c, 0x3e,
+  0x8f, 0xaa, 0xa1, 0x20, 0x0e, 0xce, 0xfd, 0x58, 0x95, 0x39, 0xa6, 0x23,
+  0x45, 0x10, 0xfd, 0x50, 0x03, 0xd7, 0xd6, 0x33, 0x81, 0x0f, 0xff, 0xa4,
+  0x8b, 0xd6, 0x98, 0xde, 0x8a, 0x53, 0x18, 0x67, 0xb6, 0x13, 0xe2, 0xdd,
+  0xac, 0xc5, 0xf2, 0x36, 0xf7, 0x76, 0xeb, 0x4d, 0xa8, 0xa5, 0x42, 0x16,
+  0xda, 0xd3, 0x20, 0xb0, 0x24, 0x22, 0xa0, 0xb7, 0x5a, 0x57, 0x58, 0xff,
+  0xff, 0xf4, 0xc4, 0x9e, 0x16, 0x72, 0xce, 0x63, 0xd0, 0xc9, 0xe2, 0x1e,
+  0x84, 0x6e, 0xb6, 0x4a, 0xfd, 0x31, 0xf9, 0xc1, 0x66, 0x2c, 0x7c, 0x2d,
+  0xcb, 0x40, 0x93, 0x89, 0x73, 0x3a, 0x4c, 0x17, 0xbb, 0xda, 0xff, 0x12,
+  0x2b, 0x86, 0xb7, 0xcb, 0x76, 0xbe, 0xd9, 0x46, 0xe0, 0x38, 0xa6, 0xd2,
+  0x41, 0x1a, 0x73, 0xb9, 0xa5, 0x6d, 0x7e, 0xbc, 0x15, 0x75, 0x56, 0xfb,
+  0x92, 0x21, 0xc6, 0x57, 0xbb, 0x03, 0x06, 0x25, 0xd3, 0x57, 0xaf, 0xa8,
+  0x03, 0xfe, 0xf0, 0x0f, 0x4e, 0xf3, 0xab, 0xbb, 0xb0, 0xc5, 0x01, 0x2e,
+  0xcd, 0x6e, 0xae, 0x93, 0xd6, 0xfd, 0x62, 0x65, 0x5e, 0x80, 0x5f, 0xea,
+  0x16, 0xae, 0x3d, 0xde, 0xe2, 0xe1, 0x72, 0x27, 0xf3, 0xf4, 0x74, 0xe3,
+  0x7c, 0x8a, 0x3d, 0x95, 0xb7, 0x82, 0x94, 0x0e, 0xa0, 0x3a, 0x07, 0xd4,
+  0x0b, 0xd7, 0x0c, 0x3e, 0x54, 0xf4, 0xa9, 0xa5, 0xae, 0x8c, 0x2c, 0x84,
+  0x74, 0x35, 0x74, 0x67, 0x68, 0xaa, 0xe8, 0x24, 0xf4, 0x82, 0xa4, 0x70,
+  0x6c, 0x45, 0x98, 0xf1, 0x81, 0x16, 0x50, 0x1f, 0x8a, 0x36, 0x31, 0xc8,
+  0x71, 0xcf, 0x45, 0x64, 0xb2, 0x92, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x79, 0x76, 0x10, 0x85, 0xf4, 0xf1, 0xd0, 0xf9, 0x0d,
+  0x98, 0x44, 0x08, 0x94, 0x24, 0x16, 0xce, 0x15, 0x17, 0xd5, 0xfb, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x79, 0x76, 0x10, 0x85, 0xf4, 0xf1, 0xd0, 0xf9, 0x0d, 0x98, 0x44, 0x08,
+  0x94, 0x24, 0x16, 0xce, 0x15, 0x17, 0xd5, 0xfb, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+  0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x65, 0xb3, 0x53,
+  0x8e, 0x60, 0xa8, 0xff, 0xeb, 0x3d, 0xe5, 0xa1, 0x97, 0xf8, 0xda, 0xb4,
+  0xc2, 0x59, 0x5a, 0x19, 0x47, 0x9f, 0xc4, 0x26, 0xb4, 0xa2, 0x44, 0xce,
+  0xb7, 0xe4, 0x8c, 0xea, 0x7f, 0xfd, 0x5d, 0x51, 0x65, 0xf3, 0x72, 0xc7,
+  0x0b, 0xb4, 0x6f, 0x01, 0x64, 0xfb, 0x68, 0x19, 0x1e, 0x82, 0xa1, 0x49,
+  0x5e, 0xe8, 0x55, 0x5f, 0x51, 0x3f, 0x68, 0x08, 0x41, 0x61, 0x27, 0x1d,
+  0xa0, 0x5a, 0xf6, 0x2a, 0x76, 0x1b, 0x67, 0x3a, 0x5c, 0x7f, 0xde, 0xa3,
+  0x34, 0x1c, 0xff, 0xfe, 0xbb, 0xcf, 0x4a, 0x8d, 0xf4, 0xc8, 0x8f, 0xf1,
+  0x2c, 0xba, 0xa3, 0xe6, 0x9e, 0x1a, 0xf1, 0xa9, 0xab, 0xfb, 0xdf, 0x72,
+  0x0f, 0x90, 0x21, 0x36, 0x0a, 0x26, 0xc3, 0x37, 0x12, 0x16, 0x92, 0xb1,
+  0x16, 0x26, 0x18, 0x50, 0x48, 0x57, 0x71, 0x69, 0xe8, 0xfd, 0x52, 0xd9,
+  0x34, 0x5e, 0x8f, 0x3b, 0x8d, 0x43, 0xb2, 0xec, 0x32, 0xbd, 0xd3, 0x98,
+  0x76, 0xe3, 0x75, 0xb7, 0xd0, 0x6e, 0x3b, 0x9e, 0x3a, 0xd2, 0x0e, 0x72,
+  0x91, 0x12, 0x16, 0x6f, 0x06, 0x9f, 0xfb, 0x76, 0x1a, 0xd2, 0xc2, 0xf7,
+  0x8c, 0xc2, 0xe8, 0xcd, 0x08, 0xaf, 0x11, 0xff, 0x91, 0xe5, 0xdb, 0xcd,
+  0xde, 0x7f, 0x6f, 0x00, 0x9a, 0xd9, 0x1c, 0x37, 0xdf, 0x47, 0x66, 0xa9,
+  0x81, 0xcc, 0xe3, 0x5f, 0xa6, 0x43, 0x20, 0xc6, 0x7f, 0x55, 0xfa, 0x84,
+  0x53, 0x3b, 0x6a, 0x75, 0x5c, 0x50, 0x18, 0x2c, 0x44, 0x14, 0x93, 0x2b,
+  0x1c, 0x46, 0xf9, 0x74, 0x2f, 0x31, 0x91, 0xfd, 0xbb, 0x8d, 0x25, 0xa8,
+  0x52, 0x5f, 0xd4, 0xb0, 0xb2, 0x71, 0x47, 0x20, 0x2c, 0x06, 0x3a, 0xc0,
+  0x7d, 0x86, 0x93, 0xb4, 0xca, 0x01, 0xb4, 0xe0, 0x82, 0xc4, 0x93, 0xac,
+  0x34, 0x0c, 0xa8, 0xe7, 0x5a, 0x68, 0x33, 0x58, 0xbf, 0xd8, 0x5b, 0xe0,
+  0xf3
 };
-unsigned int PK2_auth_len = 2048;
+unsigned int PK2_auth_len = 2029;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/PK2_delete.h b/components/service/uefi/smm_variable/test/service/auth_vectors/PK2_delete.h
index ca33bb5..067fd12 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/PK2_delete.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/PK2_delete.h
@@ -7,108 +7,106 @@
  */
 
 unsigned char PK2_delete_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x54, 0xb4, 0x06, 0x14, 0xf0,
-  0x9e, 0x6a, 0xc1, 0xcf, 0x44, 0x44, 0xef, 0x02, 0xf5, 0x79, 0x50, 0xf9,
-  0xaf, 0xf7, 0xe1, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x50, 0x4b, 0x32, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x60, 0x17, 0xf8, 0x61, 0x5d, 0x4e, 0x91, 0x73, 0xe3, 0xd4, 0x5c, 0xb9,
+  0x2d, 0xbb, 0xd0, 0xd8, 0xdc, 0x46, 0x23, 0x21, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x32, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x98, 0xcb, 0x8b, 0xd4, 0x05, 0x9b,
-  0x8d, 0x45, 0x0d, 0xed, 0xe5, 0x32, 0x38, 0x51, 0x41, 0xb1, 0xc6, 0x46,
-  0x30, 0x8d, 0xdf, 0x7d, 0xb3, 0xf9, 0x2f, 0x4b, 0x87, 0x55, 0xcc, 0xb0,
-  0x10, 0xa0, 0xbd, 0x43, 0x9c, 0x09, 0x1e, 0x7b, 0xa8, 0x50, 0x24, 0x87,
-  0x39, 0x8f, 0x3e, 0xb9, 0x33, 0x63, 0x3b, 0xd3, 0x8a, 0x08, 0x1b, 0x8f,
-  0xee, 0x11, 0x5b, 0x2b, 0x8a, 0xc2, 0xe1, 0x1e, 0x20, 0xf8, 0x41, 0x84,
-  0xc3, 0xea, 0x30, 0xaf, 0x36, 0x35, 0x6d, 0xfe, 0x78, 0x66, 0x32, 0xdf,
-  0xe4, 0x13, 0xaa, 0x3a, 0xe7, 0x78, 0xc0, 0x54, 0xc8, 0x8a, 0x05, 0xa3,
-  0x4a, 0x37, 0xc8, 0x09, 0xa8, 0x33, 0x5c, 0xb7, 0xa5, 0x6c, 0x61, 0x70,
-  0x36, 0x47, 0xae, 0xc9, 0xaf, 0xcb, 0x01, 0x85, 0x1e, 0x1f, 0x23, 0x9d,
-  0x1c, 0xc7, 0x42, 0xf0, 0x34, 0xe9, 0xb2, 0x73, 0xa0, 0x74, 0x2a, 0x87,
-  0xc2, 0xdb, 0xef, 0x3a, 0xa3, 0xca, 0x20, 0x42, 0xec, 0xd3, 0x62, 0x47,
-  0x79, 0x74, 0x7c, 0xa2, 0x72, 0x37, 0x11, 0x99, 0xff, 0x07, 0x28, 0x5e,
-  0xc7, 0x25, 0x08, 0x69, 0xa0, 0x66, 0x95, 0x8b, 0x0f, 0x89, 0x09, 0x4c,
-  0x99, 0x7d, 0x4f, 0xd5, 0x8c, 0xe2, 0xc6, 0x54, 0xa4, 0x7e, 0xd2, 0xc8,
-  0x63, 0x2a, 0x6f, 0xe1, 0x86, 0x44, 0x27, 0x16, 0x29, 0x06, 0x1f, 0x1d,
-  0x73, 0xfc, 0x9f, 0x7e, 0xf3, 0xbb, 0xae, 0xb1, 0x77, 0x54, 0x2f, 0x62,
-  0xd2, 0x79, 0xd2, 0x38, 0x6d, 0x60, 0x68, 0x3c, 0xbe, 0xae, 0x71, 0xb2,
-  0x7c, 0x06, 0x45, 0x6f, 0x5e, 0x5a, 0x44, 0x36, 0x4f, 0xf9, 0x5d, 0x4e,
-  0xe7, 0xaf, 0xde, 0x54, 0x3a, 0x0d, 0xb7, 0x19, 0x96, 0xad, 0x5e, 0x99,
-  0xac, 0x80, 0x24, 0x2d, 0x74, 0x1f, 0x35, 0xf9, 0xed, 0x30, 0x1e, 0xdc,
-  0x8b, 0x32, 0xcd, 0x25, 0xe4, 0x28, 0x27, 0x03, 0x05, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x87, 0x5a, 0x48, 0x88, 0x29, 0xf1, 0x9c,
-  0xfe, 0xfa, 0xde, 0xd7, 0xd8, 0xd9, 0x55, 0xd7, 0x22, 0x5d, 0xc2, 0x7f,
-  0x35, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x87, 0x5a, 0x48, 0x88, 0x29, 0xf1, 0x9c, 0xfe, 0xfa, 0xde,
-  0xd7, 0xd8, 0xd9, 0x55, 0xd7, 0x22, 0x5d, 0xc2, 0x7f, 0x35, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xac,
-  0xa0, 0x15, 0xab, 0xce, 0x98, 0xaa, 0x61, 0x6d, 0x3c, 0x84, 0xfa, 0x10,
-  0xed, 0xa8, 0x59, 0x32, 0x00, 0x37, 0x80, 0x96, 0xb8, 0x51, 0x0a, 0xd8,
-  0xae, 0x74, 0x4e, 0x47, 0x8a, 0x8d, 0x1b, 0xc6, 0xeb, 0x06, 0x58, 0xcd,
-  0x02, 0x73, 0xf7, 0x33, 0x6c, 0x5c, 0x7a, 0x69, 0xd5, 0x65, 0xf3, 0x85,
-  0xe8, 0x3f, 0x91, 0x3a, 0xd4, 0x7c, 0x36, 0x9a, 0xa8, 0xbb, 0xec, 0x74,
-  0x41, 0x7d, 0xd3, 0x40, 0xe4, 0x78, 0x2d, 0x36, 0x29, 0xfa, 0x58, 0x2e,
-  0xbc, 0x56, 0x40, 0x44, 0x32, 0xc6, 0x51, 0x85, 0xc2, 0x24, 0xb0, 0xaa,
-  0x0b, 0x3c, 0x06, 0x95, 0xb3, 0x6d, 0x68, 0x91, 0x99, 0x86, 0xe9, 0xb2,
-  0xba, 0x7d, 0x28, 0xdd, 0x2d, 0x67, 0x3c, 0x8c, 0x85, 0xaa, 0x6c, 0x94,
-  0xd4, 0xae, 0xfd, 0x6a, 0xaa, 0xf9, 0x53, 0x04, 0xe6, 0x13, 0x4a, 0x7b,
-  0x2c, 0x94, 0x10, 0x41, 0x74, 0x2a, 0x41, 0xdd, 0x10, 0xfc, 0x86, 0x23,
-  0x62, 0xf2, 0x9a, 0xb6, 0x41, 0xc5, 0xbd, 0x4f, 0xaa, 0xd5, 0xcc, 0x74,
-  0x9c, 0xf7, 0x3b, 0x31, 0x9a, 0xda, 0xf2, 0x20, 0x5d, 0x8a, 0x1e, 0xe3,
-  0xff, 0xd8, 0x7e, 0xa3, 0x2e, 0x8f, 0x5a, 0x30, 0x68, 0x85, 0xd6, 0x9f,
-  0xf1, 0xbd, 0x6a, 0x49, 0x64, 0x93, 0x2d, 0xb0, 0x5e, 0x68, 0x44, 0xb6,
-  0xfe, 0x64, 0x19, 0x75, 0x72, 0x49, 0x14, 0x32, 0xff, 0x0a, 0x2b, 0x15,
-  0x3f, 0xb4, 0x98, 0x69, 0xee, 0x1e, 0xbf, 0x0e, 0x14, 0x18, 0xe4, 0xc7,
-  0x78, 0x6d, 0x39, 0x5a, 0xfc, 0x41, 0x8b, 0x23, 0x42, 0xf2, 0x9f, 0x7d,
-  0x18, 0xee, 0x23, 0x6e, 0x67, 0x9f, 0xe9, 0x38, 0x51, 0x14, 0x67, 0xca,
-  0x5c, 0x75, 0xc9, 0xf3, 0x8c, 0xaa, 0x68, 0x2a, 0x28, 0xd5, 0xa4, 0x07,
-  0xbb, 0xe9, 0x5b, 0xf2, 0xde, 0x74, 0x13, 0x08, 0x6c, 0x8f, 0x31, 0x3a,
-  0x52, 0x08, 0x56, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x32, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x34, 0x32,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x34, 0x32, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
   0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x32, 0x02, 0x14, 0x54, 0xb4, 0x06, 0x14, 0xf0, 0x9e, 0x6a, 0xc1, 0xcf,
-  0x44, 0x44, 0xef, 0x02, 0xf5, 0x79, 0x50, 0xf9, 0xaf, 0xf7, 0xe1, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x2a, 0xad, 0x1c,
-  0xf0, 0x25, 0xb8, 0x5f, 0x04, 0xc8, 0xef, 0x99, 0x03, 0xce, 0x68, 0x1c,
-  0x1e, 0x78, 0x60, 0x44, 0x1f, 0x4a, 0x94, 0xe8, 0xc5, 0x12, 0x38, 0x0d,
-  0x2d, 0x21, 0x9d, 0xd8, 0x2f, 0x98, 0x58, 0x4a, 0xf4, 0x1f, 0x92, 0xf8,
-  0x9b, 0x7d, 0x7a, 0x7e, 0x43, 0xab, 0xaf, 0x6e, 0xa2, 0x59, 0xb4, 0xa0,
-  0xff, 0x91, 0xba, 0x13, 0x8a, 0x6d, 0x72, 0xcc, 0x28, 0x0d, 0xab, 0xd4,
-  0x07, 0xf1, 0xd4, 0xa5, 0xbc, 0x0f, 0x68, 0x3d, 0x2c, 0x87, 0x95, 0xe8,
-  0x4b, 0x2b, 0x55, 0x55, 0xda, 0xf8, 0x0c, 0xea, 0xfd, 0x99, 0x77, 0x5d,
-  0xbc, 0xd4, 0xae, 0x2e, 0x64, 0xb2, 0x84, 0xcb, 0x92, 0x1c, 0x83, 0x18,
-  0xc3, 0x25, 0x4d, 0x38, 0x62, 0x5b, 0x47, 0x19, 0x1f, 0x95, 0x83, 0x93,
-  0x65, 0xf9, 0x2a, 0x5f, 0x1d, 0x6d, 0xf4, 0x1c, 0xeb, 0x7e, 0xcf, 0x4d,
-  0xc8, 0xf1, 0x87, 0x32, 0xa1, 0x23, 0x62, 0xfd, 0x47, 0xb1, 0x6d, 0xe6,
-  0x30, 0x9f, 0x39, 0x67, 0x5e, 0x9f, 0x4d, 0x4c, 0x8d, 0x97, 0x0c, 0xf2,
-  0xda, 0xcb, 0xb1, 0xfa, 0x26, 0x44, 0x53, 0xa4, 0x3c, 0x5f, 0x1e, 0x49,
-  0xf9, 0xaf, 0x88, 0x37, 0xd8, 0x48, 0x00, 0xc5, 0xbb, 0x37, 0xe3, 0x6b,
-  0x6d, 0x32, 0x27, 0xc2, 0xc1, 0x14, 0x79, 0x02, 0x56, 0x46, 0xb4, 0x6b,
-  0x69, 0xe6, 0x6d, 0x01, 0x31, 0xa7, 0xaa, 0xe6, 0xb7, 0x50, 0x23, 0xac,
-  0x2c, 0x6c, 0xb2, 0x38, 0x81, 0x85, 0xfa, 0x51, 0x96, 0x3f, 0x3e, 0x7b,
-  0xef, 0xaa, 0x35, 0x4a, 0x7a, 0xfc, 0x30, 0x7b, 0x3b, 0xf0, 0xf5, 0xa1,
-  0x2d, 0x96, 0xdd, 0x13, 0x90, 0xc0, 0x3c, 0x41, 0xc0, 0x42, 0xdc, 0x5c,
-  0xb1, 0x14, 0x35, 0x0e, 0xd0, 0xda, 0xa9, 0x1a, 0x75, 0x38, 0x77, 0x7f,
-  0xa5, 0x71, 0x77, 0x7a, 0x42, 0xde, 0x64, 0x71, 0x68, 0x2e, 0x78, 0xeb,
-  0x4a
+  0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xba, 0x07,
+  0x56, 0x02, 0x70, 0xff, 0xc9, 0xc6, 0xc6, 0x8e, 0xf6, 0xf8, 0x6c, 0x99,
+  0xbf, 0x1f, 0x4d, 0x6e, 0x23, 0xc8, 0x85, 0xaf, 0x81, 0x37, 0xa1, 0x45,
+  0xe2, 0x42, 0x8e, 0x73, 0x7b, 0x6c, 0x3e, 0x8f, 0xaa, 0xa1, 0x20, 0x0e,
+  0xce, 0xfd, 0x58, 0x95, 0x39, 0xa6, 0x23, 0x45, 0x10, 0xfd, 0x50, 0x03,
+  0xd7, 0xd6, 0x33, 0x81, 0x0f, 0xff, 0xa4, 0x8b, 0xd6, 0x98, 0xde, 0x8a,
+  0x53, 0x18, 0x67, 0xb6, 0x13, 0xe2, 0xdd, 0xac, 0xc5, 0xf2, 0x36, 0xf7,
+  0x76, 0xeb, 0x4d, 0xa8, 0xa5, 0x42, 0x16, 0xda, 0xd3, 0x20, 0xb0, 0x24,
+  0x22, 0xa0, 0xb7, 0x5a, 0x57, 0x58, 0xff, 0xff, 0xf4, 0xc4, 0x9e, 0x16,
+  0x72, 0xce, 0x63, 0xd0, 0xc9, 0xe2, 0x1e, 0x84, 0x6e, 0xb6, 0x4a, 0xfd,
+  0x31, 0xf9, 0xc1, 0x66, 0x2c, 0x7c, 0x2d, 0xcb, 0x40, 0x93, 0x89, 0x73,
+  0x3a, 0x4c, 0x17, 0xbb, 0xda, 0xff, 0x12, 0x2b, 0x86, 0xb7, 0xcb, 0x76,
+  0xbe, 0xd9, 0x46, 0xe0, 0x38, 0xa6, 0xd2, 0x41, 0x1a, 0x73, 0xb9, 0xa5,
+  0x6d, 0x7e, 0xbc, 0x15, 0x75, 0x56, 0xfb, 0x92, 0x21, 0xc6, 0x57, 0xbb,
+  0x03, 0x06, 0x25, 0xd3, 0x57, 0xaf, 0xa8, 0x03, 0xfe, 0xf0, 0x0f, 0x4e,
+  0xf3, 0xab, 0xbb, 0xb0, 0xc5, 0x01, 0x2e, 0xcd, 0x6e, 0xae, 0x93, 0xd6,
+  0xfd, 0x62, 0x65, 0x5e, 0x80, 0x5f, 0xea, 0x16, 0xae, 0x3d, 0xde, 0xe2,
+  0xe1, 0x72, 0x27, 0xf3, 0xf4, 0x74, 0xe3, 0x7c, 0x8a, 0x3d, 0x95, 0xb7,
+  0x82, 0x94, 0x0e, 0xa0, 0x3a, 0x07, 0xd4, 0x0b, 0xd7, 0x0c, 0x3e, 0x54,
+  0xf4, 0xa9, 0xa5, 0xae, 0x8c, 0x2c, 0x84, 0x74, 0x35, 0x74, 0x67, 0x68,
+  0xaa, 0xe8, 0x24, 0xf4, 0x82, 0xa4, 0x70, 0x6c, 0x45, 0x98, 0xf1, 0x81,
+  0x16, 0x50, 0x1f, 0x8a, 0x36, 0x31, 0xc8, 0x71, 0xcf, 0x45, 0x64, 0xb2,
+  0x92, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x79, 0x76,
+  0x10, 0x85, 0xf4, 0xf1, 0xd0, 0xf9, 0x0d, 0x98, 0x44, 0x08, 0x94, 0x24,
+  0x16, 0xce, 0x15, 0x17, 0xd5, 0xfb, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x79, 0x76, 0x10, 0x85, 0xf4,
+  0xf1, 0xd0, 0xf9, 0x0d, 0x98, 0x44, 0x08, 0x94, 0x24, 0x16, 0xce, 0x15,
+  0x17, 0xd5, 0xfb, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x65, 0xb3, 0x53, 0x8e, 0x60, 0xa8, 0xff, 0xeb,
+  0x3d, 0xe5, 0xa1, 0x97, 0xf8, 0xda, 0xb4, 0xc2, 0x59, 0x5a, 0x19, 0x47,
+  0x9f, 0xc4, 0x26, 0xb4, 0xa2, 0x44, 0xce, 0xb7, 0xe4, 0x8c, 0xea, 0x7f,
+  0xfd, 0x5d, 0x51, 0x65, 0xf3, 0x72, 0xc7, 0x0b, 0xb4, 0x6f, 0x01, 0x64,
+  0xfb, 0x68, 0x19, 0x1e, 0x82, 0xa1, 0x49, 0x5e, 0xe8, 0x55, 0x5f, 0x51,
+  0x3f, 0x68, 0x08, 0x41, 0x61, 0x27, 0x1d, 0xa0, 0x5a, 0xf6, 0x2a, 0x76,
+  0x1b, 0x67, 0x3a, 0x5c, 0x7f, 0xde, 0xa3, 0x34, 0x1c, 0xff, 0xfe, 0xbb,
+  0xcf, 0x4a, 0x8d, 0xf4, 0xc8, 0x8f, 0xf1, 0x2c, 0xba, 0xa3, 0xe6, 0x9e,
+  0x1a, 0xf1, 0xa9, 0xab, 0xfb, 0xdf, 0x72, 0x0f, 0x90, 0x21, 0x36, 0x0a,
+  0x26, 0xc3, 0x37, 0x12, 0x16, 0x92, 0xb1, 0x16, 0x26, 0x18, 0x50, 0x48,
+  0x57, 0x71, 0x69, 0xe8, 0xfd, 0x52, 0xd9, 0x34, 0x5e, 0x8f, 0x3b, 0x8d,
+  0x43, 0xb2, 0xec, 0x32, 0xbd, 0xd3, 0x98, 0x76, 0xe3, 0x75, 0xb7, 0xd0,
+  0x6e, 0x3b, 0x9e, 0x3a, 0xd2, 0x0e, 0x72, 0x91, 0x12, 0x16, 0x6f, 0x06,
+  0x9f, 0xfb, 0x76, 0x1a, 0xd2, 0xc2, 0xf7, 0x8c, 0xc2, 0xe8, 0xcd, 0x08,
+  0xaf, 0x11, 0xff, 0x91, 0xe5, 0xdb, 0xcd, 0xde, 0x7f, 0x6f, 0x00, 0x9a,
+  0xd9, 0x1c, 0x37, 0xdf, 0x47, 0x66, 0xa9, 0x81, 0xcc, 0xe3, 0x5f, 0xa6,
+  0x43, 0x20, 0xc6, 0x7f, 0x55, 0xfa, 0x84, 0x53, 0x3b, 0x6a, 0x75, 0x5c,
+  0x50, 0x18, 0x2c, 0x44, 0x14, 0x93, 0x2b, 0x1c, 0x46, 0xf9, 0x74, 0x2f,
+  0x31, 0x91, 0xfd, 0xbb, 0x8d, 0x25, 0xa8, 0x52, 0x5f, 0xd4, 0xb0, 0xb2,
+  0x71, 0x47, 0x20, 0x2c, 0x06, 0x3a, 0xc0, 0x7d, 0x86, 0x93, 0xb4, 0xca,
+  0x01, 0xb4, 0xe0, 0x82, 0xc4, 0x93, 0xac, 0x34, 0x0c, 0xa8, 0xe7, 0x5a,
+  0x68, 0x33, 0x58, 0xbf, 0xd8, 0x5b, 0xe0, 0xf3, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x32, 0x02, 0x14, 0x60, 0x17, 0xf8, 0x61,
+  0x5d, 0x4e, 0x91, 0x73, 0xe3, 0xd4, 0x5c, 0xb9, 0x2d, 0xbb, 0xd0, 0xd8,
+  0xdc, 0x46, 0x23, 0x21, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x4f, 0xbe, 0xbc, 0xc6, 0x01, 0x50, 0xd2, 0x31, 0x5e, 0xf3,
+  0x86, 0x4d, 0x15, 0xac, 0x03, 0x6a, 0x47, 0xca, 0x93, 0x33, 0x84, 0x77,
+  0x38, 0xac, 0x2f, 0xe7, 0xc7, 0x51, 0x2d, 0x1e, 0x3e, 0x49, 0x88, 0x01,
+  0xf8, 0x66, 0xf6, 0x2f, 0xe0, 0xf2, 0xe0, 0x49, 0xce, 0x9f, 0x63, 0x39,
+  0x4c, 0x1f, 0x98, 0x96, 0xc9, 0x38, 0x02, 0x07, 0xe3, 0x17, 0x45, 0xb9,
+  0x60, 0x07, 0x27, 0x16, 0x3e, 0x37, 0xb3, 0x23, 0x8a, 0xa4, 0xc9, 0xf7,
+  0xae, 0xed, 0x5c, 0xc5, 0x0d, 0xa4, 0x30, 0x63, 0xa1, 0x32, 0x0e, 0xd3,
+  0x36, 0xe7, 0xa8, 0xd8, 0xbb, 0x27, 0x28, 0x72, 0xd9, 0xbe, 0xcd, 0x22,
+  0xbb, 0xab, 0x14, 0x21, 0x6a, 0xa0, 0xb3, 0xa7, 0x30, 0xf3, 0x35, 0xee,
+  0xb4, 0x83, 0xa1, 0x3c, 0x86, 0x2d, 0xe3, 0x52, 0x53, 0x57, 0xc6, 0x41,
+  0x4f, 0x54, 0x42, 0xd1, 0x6a, 0x92, 0x04, 0x5c, 0x7d, 0xb1, 0x33, 0x86,
+  0x7a, 0x80, 0xb7, 0x43, 0xaa, 0xd6, 0xe6, 0x55, 0xfb, 0xc2, 0x53, 0xc6,
+  0x27, 0x36, 0x23, 0xb9, 0x79, 0xbe, 0x31, 0xd9, 0x29, 0x81, 0xce, 0x71,
+  0x24, 0x29, 0xc9, 0x2c, 0xb1, 0x2b, 0xc7, 0xb3, 0x2f, 0x2e, 0x6b, 0xf0,
+  0xeb, 0x2b, 0x1d, 0x6a, 0x4c, 0x2c, 0xbf, 0xf6, 0x31, 0xc5, 0x4c, 0x13,
+  0x37, 0x39, 0xef, 0xfe, 0x55, 0x51, 0x69, 0x71, 0x0f, 0xe4, 0x3f, 0x86,
+  0xc8, 0x61, 0x1d, 0x25, 0xac, 0x03, 0xc8, 0xfc, 0xff, 0x38, 0x9b, 0x6c,
+  0x74, 0x92, 0xa5, 0x35, 0x23, 0x8e, 0x11, 0xa3, 0x82, 0xbc, 0xe7, 0x61,
+  0x98, 0x4c, 0x3d, 0xdf, 0xa3, 0x88, 0x1b, 0xe1, 0x57, 0x95, 0xe6, 0xac,
+  0xd9, 0xb3, 0xa3, 0xba, 0x09, 0x12, 0xf5, 0x3c, 0xc4, 0xec, 0x8e, 0x51,
+  0x56, 0x02, 0x7d, 0x17, 0x06, 0x71, 0x1e, 0xcd, 0xdc, 0x2e, 0x10, 0xbb,
+  0x11, 0xbf, 0xf1, 0x8f, 0xac, 0xa2
 };
-unsigned int PK2_delete_auth_len = 1225;
+unsigned int PK2_delete_auth_len = 1206;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/PK3.h b/components/service/uefi/smm_variable/test/service/auth_vectors/PK3.h
index 5a0a39d..2944524 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/PK3.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/PK3.h
@@ -7,176 +7,175 @@
  */
 
 unsigned char PK3_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x37, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x11, 0x90, 0xbd, 0xc1, 0x8a,
-  0x36, 0x84, 0x80, 0x84, 0xa0, 0xe2, 0x8f, 0x57, 0xc9, 0x25, 0x01, 0xd7,
-  0x71, 0x9f, 0x6f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x50, 0x4b, 0x33, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
-  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x33, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xd4, 0x89, 0x82, 0x3f, 0x53, 0x8c, 0x94,
-  0xba, 0xbf, 0xff, 0xfd, 0x18, 0x9b, 0xa0, 0x30, 0x7e, 0x56, 0xd7, 0xe1,
-  0xdb, 0x77, 0x88, 0x35, 0xa8, 0x20, 0x69, 0xe2, 0x3a, 0xcf, 0x0b, 0x87,
-  0xd0, 0x06, 0x39, 0x83, 0x46, 0x15, 0xe8, 0x36, 0xf1, 0xf5, 0x3e, 0x46,
-  0xed, 0xa8, 0x8c, 0x11, 0x33, 0x9f, 0x72, 0xc0, 0x57, 0xd0, 0x06, 0x35,
-  0x06, 0xc7, 0xd5, 0xdb, 0xeb, 0x3d, 0x12, 0xc4, 0xc2, 0x0c, 0x5e, 0x14,
-  0xf4, 0x7c, 0x3a, 0xd8, 0x55, 0x37, 0xcd, 0x55, 0x2c, 0x37, 0x98, 0x2b,
-  0xdb, 0x3b, 0xfe, 0x70, 0x06, 0x56, 0x64, 0x03, 0x64, 0x13, 0xd6, 0x73,
-  0xf3, 0x93, 0x8b, 0xc3, 0x37, 0xa5, 0xb7, 0xa0, 0x40, 0xb6, 0x3d, 0x7e,
-  0x79, 0x86, 0xc6, 0x33, 0x3c, 0x2a, 0x5a, 0x0f, 0x91, 0x91, 0xef, 0xdb,
-  0xca, 0x47, 0x58, 0x83, 0xde, 0x22, 0x81, 0x8f, 0x19, 0x49, 0x6f, 0x3b,
-  0xae, 0x06, 0xad, 0xda, 0xb6, 0xad, 0x04, 0x62, 0xe2, 0xb0, 0x14, 0xc4,
-  0xb0, 0xc3, 0x7d, 0x2f, 0x48, 0x19, 0x75, 0xd0, 0xda, 0x81, 0x60, 0x0d,
-  0x03, 0xbd, 0x1b, 0xfd, 0xb6, 0x10, 0x7b, 0x23, 0x4e, 0x91, 0xa6, 0xff,
-  0xbd, 0xd5, 0xfe, 0xd7, 0x3f, 0x63, 0x53, 0x1f, 0x48, 0xe5, 0xc9, 0x6d,
-  0x69, 0xcd, 0x0e, 0xde, 0x54, 0xe3, 0x42, 0xb6, 0xdc, 0x12, 0x2e, 0x0c,
-  0xcf, 0x40, 0x58, 0x52, 0xef, 0xad, 0x8d, 0xf4, 0x52, 0x56, 0xda, 0x3b,
-  0x47, 0xb1, 0x4c, 0xc6, 0xe1, 0x3a, 0x6f, 0x28, 0xe9, 0xf9, 0x10, 0x86,
-  0x37, 0x24, 0x74, 0xe5, 0x03, 0xb1, 0x95, 0x71, 0xe4, 0xf4, 0xe5, 0xaa,
-  0xb3, 0x88, 0x15, 0x20, 0x3c, 0xc8, 0x00, 0x2d, 0x04, 0x4a, 0x7e, 0x35,
-  0x7c, 0x70, 0xb1, 0xa6, 0xad, 0x82, 0xa0, 0x77, 0xb5, 0x4d, 0xd4, 0x92,
-  0x0c, 0x9a, 0xca, 0x8b, 0xdd, 0x75, 0x28, 0xae, 0x99, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0xae, 0xfa, 0xbf, 0x66, 0xb9, 0xc6, 0xf2,
-  0x3b, 0x01, 0x7f, 0x52, 0x90, 0x41, 0x6d, 0x0e, 0x33, 0x51, 0x01, 0x7c,
-  0x7e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0xae, 0xfa, 0xbf, 0x66, 0xb9, 0xc6, 0xf2, 0x3b, 0x01, 0x7f,
-  0x52, 0x90, 0x41, 0x6d, 0x0e, 0x33, 0x51, 0x01, 0x7c, 0x7e, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xb8,
-  0xdb, 0x9a, 0x38, 0x6e, 0xb1, 0x48, 0xe0, 0x5a, 0x9b, 0xd5, 0xec, 0x2e,
-  0xe5, 0x8a, 0xb5, 0xc7, 0x4e, 0x9f, 0xe9, 0x8d, 0xde, 0x11, 0xc5, 0xe0,
-  0x8a, 0x75, 0xe6, 0x04, 0x7e, 0xfa, 0xcb, 0x3e, 0xa2, 0xb8, 0x28, 0xf3,
-  0xbc, 0xc5, 0xaf, 0x6d, 0x2a, 0x45, 0x34, 0x91, 0x62, 0xf5, 0xe1, 0x66,
-  0x7f, 0x82, 0xd9, 0xac, 0xc4, 0x29, 0x36, 0xed, 0xcb, 0x8a, 0x97, 0x88,
-  0x6c, 0x8f, 0xa1, 0x19, 0xbd, 0x04, 0xe1, 0x1c, 0x95, 0x7f, 0x45, 0xe3,
-  0x8c, 0xda, 0x74, 0xa7, 0xd9, 0x4d, 0x41, 0x34, 0x96, 0x77, 0xe0, 0x68,
-  0xd7, 0x7b, 0xff, 0x62, 0x1d, 0xa3, 0xaf, 0x12, 0xdc, 0x6a, 0xf1, 0xaf,
-  0x09, 0xa2, 0xc6, 0x72, 0xa4, 0xbb, 0xcf, 0xd4, 0x96, 0xae, 0x41, 0xfc,
-  0x77, 0x56, 0xe7, 0xe0, 0x8e, 0x0a, 0x80, 0xd5, 0xc1, 0xb4, 0xfd, 0xa9,
-  0xf4, 0x8d, 0xc8, 0x26, 0xf8, 0x21, 0x0b, 0x8c, 0xc3, 0x6a, 0x75, 0x46,
-  0xf2, 0x3f, 0x5c, 0x42, 0xd6, 0xe4, 0x98, 0x73, 0x72, 0x9a, 0x34, 0x71,
-  0x4f, 0xa2, 0x97, 0x2e, 0x63, 0x1f, 0x38, 0x25, 0x1c, 0xb8, 0xf8, 0xec,
-  0xc0, 0x60, 0x14, 0x9a, 0x9d, 0x91, 0xc0, 0x0e, 0xbb, 0x23, 0xfc, 0x25,
-  0x8b, 0x01, 0x20, 0x2d, 0x30, 0x0f, 0x25, 0xa7, 0x0a, 0xbe, 0x91, 0xf3,
-  0xb5, 0x15, 0x77, 0x07, 0x59, 0x4a, 0x3a, 0xc7, 0x1b, 0xb9, 0xc9, 0x48,
-  0xa4, 0xfe, 0x05, 0xe2, 0x50, 0x89, 0x26, 0xd8, 0x13, 0xe1, 0xd2, 0xe4,
-  0x5d, 0x34, 0xa3, 0x8f, 0x99, 0x00, 0xd0, 0x11, 0x13, 0x97, 0x4c, 0x41,
-  0x2d, 0x63, 0xdf, 0xb6, 0xa6, 0xc1, 0xb5, 0x9f, 0x08, 0xda, 0x44, 0xd1,
-  0x80, 0x1d, 0xe3, 0x82, 0x12, 0x5e, 0xa8, 0x63, 0x8f, 0x74, 0xf2, 0xab,
-  0xbb, 0xf6, 0xca, 0x2a, 0x51, 0xa2, 0xc2, 0xcc, 0x85, 0x37, 0x85, 0x97,
-  0x1a, 0x4c, 0x3e, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x33, 0x02, 0x14, 0x11, 0x90, 0xbd, 0xc1, 0x8a, 0x36, 0x84, 0x80, 0x84,
-  0xa0, 0xe2, 0x8f, 0x57, 0xc9, 0x25, 0x01, 0xd7, 0x71, 0x9f, 0x6f, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x00, 0x8c, 0x4d,
-  0xfa, 0xc3, 0xc1, 0x69, 0x2f, 0x8f, 0x25, 0x46, 0x68, 0xf4, 0x57, 0x99,
-  0xd3, 0xd0, 0xb9, 0x01, 0xc0, 0xec, 0xc3, 0xe7, 0x22, 0x72, 0xeb, 0xab,
-  0x72, 0xc3, 0x5f, 0x70, 0x9b, 0x83, 0xb7, 0xf0, 0x7e, 0x8e, 0x42, 0x35,
-  0x8d, 0xf9, 0x32, 0xe0, 0x07, 0x38, 0x9d, 0x0a, 0x0f, 0x64, 0xaf, 0x45,
-  0xc6, 0xfe, 0x2d, 0x6a, 0x3a, 0xe5, 0x2e, 0xd4, 0xae, 0x9b, 0x7d, 0x05,
-  0x73, 0x3b, 0xa0, 0xbb, 0x64, 0x91, 0xd9, 0x44, 0x9d, 0xdb, 0x05, 0xec,
-  0xca, 0x2c, 0x25, 0xc3, 0xa1, 0xc3, 0x89, 0x40, 0x03, 0x53, 0x78, 0x42,
-  0x55, 0x14, 0x30, 0xba, 0xeb, 0xa3, 0x4b, 0xc4, 0x53, 0xc9, 0x20, 0xd2,
-  0x41, 0x89, 0xa9, 0x00, 0x48, 0xac, 0x90, 0xea, 0xef, 0x31, 0x9a, 0x79,
-  0xd0, 0x9d, 0x20, 0xdf, 0x80, 0x0f, 0x2c, 0xd1, 0x13, 0x5e, 0x7a, 0xc4,
-  0x08, 0x07, 0xd6, 0xe7, 0x49, 0xd3, 0x05, 0x95, 0xb5, 0xbd, 0x19, 0xfb,
-  0x97, 0x1b, 0xd6, 0xd4, 0x2f, 0xfb, 0x3c, 0xbb, 0xa9, 0xc4, 0xd3, 0x6f,
-  0xda, 0x40, 0x02, 0x39, 0xad, 0x90, 0xb7, 0xa2, 0x36, 0xe7, 0x72, 0xf7,
-  0xb6, 0xdf, 0x2f, 0x68, 0x02, 0xb0, 0x66, 0x37, 0x6e, 0x4f, 0xe3, 0x5b,
-  0x5f, 0x4b, 0x17, 0x1f, 0x36, 0x02, 0x81, 0x5a, 0x32, 0x41, 0x0d, 0xd1,
-  0xbb, 0x02, 0xcb, 0x46, 0x95, 0xdf, 0x92, 0xde, 0x23, 0x28, 0x71, 0x77,
-  0x1c, 0xf1, 0x77, 0x2e, 0x1b, 0xe4, 0x62, 0x00, 0x78, 0x28, 0x94, 0x2b,
-  0x06, 0x46, 0x6e, 0x29, 0x09, 0x78, 0x30, 0xa5, 0xb9, 0x4e, 0x70, 0xcb,
-  0x1b, 0x01, 0xd8, 0x6c, 0x6b, 0xdc, 0xcf, 0xd4, 0xc3, 0x03, 0xe0, 0xd5,
-  0x4e, 0x6a, 0x8d, 0x4b, 0x62, 0xe5, 0x42, 0xf2, 0x62, 0x30, 0x1f, 0x53,
-  0xd8, 0x8e, 0x57, 0xa8, 0xef, 0xfc, 0x87, 0x31, 0x08, 0xfd, 0xc6, 0xf0,
-  0x3c, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab,
-  0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x03,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
   0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
-  0x11, 0x90, 0xbd, 0xc1, 0x8a, 0x36, 0x84, 0x80, 0x84, 0xa0, 0xe2, 0x8f,
-  0x57, 0xc9, 0x25, 0x01, 0xd7, 0x71, 0x9f, 0x6f, 0x30, 0x0d, 0x06, 0x09,
+  0x38, 0x39, 0x6f, 0x5f, 0x80, 0x6d, 0xcf, 0xd1, 0x4e, 0x2f, 0x53, 0x68,
+  0x40, 0x42, 0xef, 0x69, 0xa1, 0xfe, 0x99, 0xf5, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
   0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x33, 0x30, 0x1e, 0x17, 0x0d,
-  0x32, 0x34, 0x30, 0x31, 0x32, 0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38,
-  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32,
-  0x30, 0x30, 0x38, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x34, 0x34,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x34, 0x34, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
   0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
   0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
   0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
-  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd4, 0x89,
-  0x82, 0x3f, 0x53, 0x8c, 0x94, 0xba, 0xbf, 0xff, 0xfd, 0x18, 0x9b, 0xa0,
-  0x30, 0x7e, 0x56, 0xd7, 0xe1, 0xdb, 0x77, 0x88, 0x35, 0xa8, 0x20, 0x69,
-  0xe2, 0x3a, 0xcf, 0x0b, 0x87, 0xd0, 0x06, 0x39, 0x83, 0x46, 0x15, 0xe8,
-  0x36, 0xf1, 0xf5, 0x3e, 0x46, 0xed, 0xa8, 0x8c, 0x11, 0x33, 0x9f, 0x72,
-  0xc0, 0x57, 0xd0, 0x06, 0x35, 0x06, 0xc7, 0xd5, 0xdb, 0xeb, 0x3d, 0x12,
-  0xc4, 0xc2, 0x0c, 0x5e, 0x14, 0xf4, 0x7c, 0x3a, 0xd8, 0x55, 0x37, 0xcd,
-  0x55, 0x2c, 0x37, 0x98, 0x2b, 0xdb, 0x3b, 0xfe, 0x70, 0x06, 0x56, 0x64,
-  0x03, 0x64, 0x13, 0xd6, 0x73, 0xf3, 0x93, 0x8b, 0xc3, 0x37, 0xa5, 0xb7,
-  0xa0, 0x40, 0xb6, 0x3d, 0x7e, 0x79, 0x86, 0xc6, 0x33, 0x3c, 0x2a, 0x5a,
-  0x0f, 0x91, 0x91, 0xef, 0xdb, 0xca, 0x47, 0x58, 0x83, 0xde, 0x22, 0x81,
-  0x8f, 0x19, 0x49, 0x6f, 0x3b, 0xae, 0x06, 0xad, 0xda, 0xb6, 0xad, 0x04,
-  0x62, 0xe2, 0xb0, 0x14, 0xc4, 0xb0, 0xc3, 0x7d, 0x2f, 0x48, 0x19, 0x75,
-  0xd0, 0xda, 0x81, 0x60, 0x0d, 0x03, 0xbd, 0x1b, 0xfd, 0xb6, 0x10, 0x7b,
-  0x23, 0x4e, 0x91, 0xa6, 0xff, 0xbd, 0xd5, 0xfe, 0xd7, 0x3f, 0x63, 0x53,
-  0x1f, 0x48, 0xe5, 0xc9, 0x6d, 0x69, 0xcd, 0x0e, 0xde, 0x54, 0xe3, 0x42,
-  0xb6, 0xdc, 0x12, 0x2e, 0x0c, 0xcf, 0x40, 0x58, 0x52, 0xef, 0xad, 0x8d,
-  0xf4, 0x52, 0x56, 0xda, 0x3b, 0x47, 0xb1, 0x4c, 0xc6, 0xe1, 0x3a, 0x6f,
-  0x28, 0xe9, 0xf9, 0x10, 0x86, 0x37, 0x24, 0x74, 0xe5, 0x03, 0xb1, 0x95,
-  0x71, 0xe4, 0xf4, 0xe5, 0xaa, 0xb3, 0x88, 0x15, 0x20, 0x3c, 0xc8, 0x00,
-  0x2d, 0x04, 0x4a, 0x7e, 0x35, 0x7c, 0x70, 0xb1, 0xa6, 0xad, 0x82, 0xa0,
-  0x77, 0xb5, 0x4d, 0xd4, 0x92, 0x0c, 0x9a, 0xca, 0x8b, 0xdd, 0x75, 0x28,
-  0xae, 0x99, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
-  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xae, 0xfa,
-  0xbf, 0x66, 0xb9, 0xc6, 0xf2, 0x3b, 0x01, 0x7f, 0x52, 0x90, 0x41, 0x6d,
-  0x0e, 0x33, 0x51, 0x01, 0x7c, 0x7e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
-  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xae, 0xfa, 0xbf, 0x66, 0xb9,
-  0xc6, 0xf2, 0x3b, 0x01, 0x7f, 0x52, 0x90, 0x41, 0x6d, 0x0e, 0x33, 0x51,
-  0x01, 0x7c, 0x7e, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc5, 0xa4,
+  0x45, 0xe2, 0xed, 0x42, 0x14, 0xcc, 0x23, 0x8f, 0x88, 0xd1, 0x25, 0xad,
+  0x09, 0xce, 0x76, 0x2a, 0xdf, 0x7f, 0xe5, 0x91, 0x68, 0x57, 0x47, 0xfc,
+  0xc0, 0x89, 0x58, 0xbe, 0x5d, 0xb8, 0xf0, 0x27, 0x14, 0xc6, 0x55, 0x1e,
+  0x77, 0xac, 0xdd, 0xa9, 0x68, 0x3b, 0x5d, 0x70, 0x8f, 0x46, 0x23, 0x79,
+  0x04, 0xaa, 0x4c, 0xac, 0x0b, 0x48, 0x34, 0x26, 0xf7, 0x17, 0xa3, 0x60,
+  0x99, 0x62, 0x20, 0x7f, 0x72, 0x28, 0x48, 0x1e, 0x7f, 0x80, 0x31, 0xd6,
+  0xd3, 0xa2, 0x5c, 0x96, 0xf1, 0x8d, 0x66, 0x1c, 0x68, 0x0e, 0x67, 0x17,
+  0x98, 0x75, 0xc1, 0x02, 0x8f, 0x9f, 0x6b, 0x7e, 0x56, 0x8c, 0xfc, 0x09,
+  0x93, 0xf8, 0xbb, 0x7e, 0x45, 0x8d, 0x29, 0x6c, 0xb3, 0xf1, 0x72, 0xf5,
+  0x51, 0xec, 0x89, 0xfa, 0x1f, 0xfb, 0x58, 0x48, 0x7b, 0x04, 0x4e, 0x28,
+  0xaf, 0x4a, 0xc4, 0x21, 0xc8, 0x4d, 0x16, 0x60, 0x7d, 0x56, 0x71, 0x9b,
+  0x56, 0x29, 0xaa, 0x31, 0xa1, 0x28, 0xa8, 0x6e, 0x6e, 0xfe, 0x02, 0xf8,
+  0x3b, 0x9a, 0xc6, 0xf2, 0xd1, 0x6c, 0xab, 0xaf, 0x75, 0xc8, 0xdb, 0xd6,
+  0x78, 0x66, 0x29, 0x78, 0x67, 0x65, 0x6c, 0x9d, 0x21, 0xb9, 0x3d, 0x7f,
+  0x72, 0x02, 0x8e, 0x00, 0x13, 0xe2, 0x13, 0x9f, 0xb8, 0x18, 0xe8, 0x61,
+  0x7c, 0x55, 0xd3, 0xa5, 0xd9, 0x93, 0x9f, 0x93, 0xed, 0x67, 0x5a, 0x1a,
+  0x1d, 0x01, 0x32, 0xfd, 0xcb, 0x26, 0xac, 0xfc, 0x89, 0x71, 0x4d, 0x8f,
+  0xf2, 0xfb, 0x04, 0xae, 0x0f, 0x8e, 0xbd, 0xdf, 0x7f, 0xb8, 0xe5, 0xcb,
+  0xc4, 0xd7, 0x7b, 0xfd, 0xa1, 0x70, 0x0b, 0xd3, 0xe3, 0xcf, 0xf1, 0x70,
+  0x0e, 0x50, 0xca, 0x54, 0x8c, 0xaf, 0xdc, 0xb2, 0x45, 0x82, 0xe4, 0xb6,
+  0xc7, 0x26, 0x2e, 0x7d, 0x8e, 0x2d, 0xc9, 0x2a, 0x22, 0x8e, 0x27, 0x07,
+  0x32, 0x51, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x95, 0x6e,
+  0xcf, 0x47, 0x75, 0x35, 0xd0, 0x19, 0xe5, 0x5a, 0x9a, 0xb0, 0x88, 0x48,
+  0xe0, 0xf4, 0xf4, 0x14, 0x3c, 0x85, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x95, 0x6e, 0xcf, 0x47, 0x75,
+  0x35, 0xd0, 0x19, 0xe5, 0x5a, 0x9a, 0xb0, 0x88, 0x48, 0xe0, 0xf4, 0xf4,
+  0x14, 0x3c, 0x85, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
   0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
-  0x82, 0x01, 0x01, 0x00, 0xb8, 0xdb, 0x9a, 0x38, 0x6e, 0xb1, 0x48, 0xe0,
-  0x5a, 0x9b, 0xd5, 0xec, 0x2e, 0xe5, 0x8a, 0xb5, 0xc7, 0x4e, 0x9f, 0xe9,
-  0x8d, 0xde, 0x11, 0xc5, 0xe0, 0x8a, 0x75, 0xe6, 0x04, 0x7e, 0xfa, 0xcb,
-  0x3e, 0xa2, 0xb8, 0x28, 0xf3, 0xbc, 0xc5, 0xaf, 0x6d, 0x2a, 0x45, 0x34,
-  0x91, 0x62, 0xf5, 0xe1, 0x66, 0x7f, 0x82, 0xd9, 0xac, 0xc4, 0x29, 0x36,
-  0xed, 0xcb, 0x8a, 0x97, 0x88, 0x6c, 0x8f, 0xa1, 0x19, 0xbd, 0x04, 0xe1,
-  0x1c, 0x95, 0x7f, 0x45, 0xe3, 0x8c, 0xda, 0x74, 0xa7, 0xd9, 0x4d, 0x41,
-  0x34, 0x96, 0x77, 0xe0, 0x68, 0xd7, 0x7b, 0xff, 0x62, 0x1d, 0xa3, 0xaf,
-  0x12, 0xdc, 0x6a, 0xf1, 0xaf, 0x09, 0xa2, 0xc6, 0x72, 0xa4, 0xbb, 0xcf,
-  0xd4, 0x96, 0xae, 0x41, 0xfc, 0x77, 0x56, 0xe7, 0xe0, 0x8e, 0x0a, 0x80,
-  0xd5, 0xc1, 0xb4, 0xfd, 0xa9, 0xf4, 0x8d, 0xc8, 0x26, 0xf8, 0x21, 0x0b,
-  0x8c, 0xc3, 0x6a, 0x75, 0x46, 0xf2, 0x3f, 0x5c, 0x42, 0xd6, 0xe4, 0x98,
-  0x73, 0x72, 0x9a, 0x34, 0x71, 0x4f, 0xa2, 0x97, 0x2e, 0x63, 0x1f, 0x38,
-  0x25, 0x1c, 0xb8, 0xf8, 0xec, 0xc0, 0x60, 0x14, 0x9a, 0x9d, 0x91, 0xc0,
-  0x0e, 0xbb, 0x23, 0xfc, 0x25, 0x8b, 0x01, 0x20, 0x2d, 0x30, 0x0f, 0x25,
-  0xa7, 0x0a, 0xbe, 0x91, 0xf3, 0xb5, 0x15, 0x77, 0x07, 0x59, 0x4a, 0x3a,
-  0xc7, 0x1b, 0xb9, 0xc9, 0x48, 0xa4, 0xfe, 0x05, 0xe2, 0x50, 0x89, 0x26,
-  0xd8, 0x13, 0xe1, 0xd2, 0xe4, 0x5d, 0x34, 0xa3, 0x8f, 0x99, 0x00, 0xd0,
-  0x11, 0x13, 0x97, 0x4c, 0x41, 0x2d, 0x63, 0xdf, 0xb6, 0xa6, 0xc1, 0xb5,
-  0x9f, 0x08, 0xda, 0x44, 0xd1, 0x80, 0x1d, 0xe3, 0x82, 0x12, 0x5e, 0xa8,
-  0x63, 0x8f, 0x74, 0xf2, 0xab, 0xbb, 0xf6, 0xca, 0x2a, 0x51, 0xa2, 0xc2,
-  0xcc, 0x85, 0x37, 0x85, 0x97, 0x1a, 0x4c, 0x3e
+  0x82, 0x01, 0x01, 0x00, 0x86, 0xba, 0x2b, 0x96, 0x5e, 0x22, 0x2b, 0xef,
+  0x74, 0xc6, 0xf2, 0xbc, 0xbe, 0x21, 0xa8, 0x27, 0x2a, 0x17, 0x7c, 0xf9,
+  0xe5, 0xc4, 0x85, 0x15, 0x51, 0xaa, 0xe7, 0x2b, 0xe5, 0xda, 0xb6, 0xb4,
+  0x8f, 0xd3, 0xd1, 0x79, 0x19, 0xfb, 0x50, 0x82, 0x44, 0xfc, 0x43, 0xcd,
+  0xb5, 0x84, 0xa9, 0xfa, 0xe4, 0x46, 0xd3, 0x8b, 0x80, 0x5a, 0x7a, 0xb0,
+  0x2f, 0x13, 0x12, 0x26, 0xa9, 0xb6, 0x15, 0x8d, 0x15, 0x37, 0x6f, 0x1e,
+  0xd2, 0x40, 0xb1, 0xc4, 0x1e, 0x58, 0x92, 0xe8, 0xc8, 0x89, 0xe5, 0x1e,
+  0x5e, 0x2c, 0x55, 0xa9, 0x9e, 0x12, 0xab, 0x7c, 0x7b, 0x07, 0xa9, 0xc8,
+  0x02, 0x72, 0xc1, 0x14, 0xc6, 0x5e, 0xc8, 0xf9, 0xa8, 0x3f, 0xd4, 0x66,
+  0x97, 0x08, 0x34, 0x05, 0x36, 0x66, 0xcf, 0x6f, 0x06, 0x56, 0x56, 0x2b,
+  0xad, 0xb8, 0x13, 0x3f, 0xdb, 0x77, 0xd8, 0xd9, 0xf7, 0xb8, 0x12, 0x23,
+  0xbf, 0xda, 0x11, 0xd9, 0x7d, 0x1d, 0xdc, 0x38, 0xd4, 0x01, 0x43, 0x23,
+  0xea, 0xa4, 0x53, 0x75, 0x53, 0x06, 0xb5, 0xc9, 0xd5, 0x44, 0x9f, 0xbc,
+  0xd8, 0x31, 0xab, 0xb5, 0x5a, 0xb5, 0xbf, 0xd2, 0xf9, 0x2a, 0x39, 0xc9,
+  0x3c, 0x58, 0x7c, 0x50, 0x0e, 0x1d, 0x6e, 0x59, 0xf0, 0x94, 0x25, 0x16,
+  0x44, 0x6c, 0x07, 0x98, 0xc1, 0x02, 0xad, 0xb9, 0x1b, 0xac, 0x2f, 0x6b,
+  0x4a, 0xb3, 0x49, 0xd6, 0xfa, 0xa6, 0x71, 0xa4, 0xbc, 0x15, 0xec, 0x7f,
+  0x4e, 0x6e, 0xfd, 0x61, 0x43, 0x5b, 0xd9, 0x89, 0xc7, 0x7a, 0xed, 0xa2,
+  0x3a, 0x4b, 0x5a, 0x70, 0x82, 0x20, 0xb0, 0x98, 0x00, 0x01, 0x5d, 0xae,
+  0xb2, 0xcc, 0x52, 0xf3, 0x9e, 0x42, 0xc8, 0xc0, 0xb1, 0xb6, 0x7a, 0xa3,
+  0xf1, 0x67, 0xbd, 0x42, 0xdd, 0xa0, 0xda, 0x1f, 0x3d, 0xb7, 0xc1, 0x76,
+  0xfb, 0x3c, 0x4b, 0x5d, 0x16, 0x56, 0x9c, 0xc7, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x33, 0x02, 0x14, 0x38, 0x39, 0x6f, 0x5f,
+  0x80, 0x6d, 0xcf, 0xd1, 0x4e, 0x2f, 0x53, 0x68, 0x40, 0x42, 0xef, 0x69,
+  0xa1, 0xfe, 0x99, 0xf5, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x85, 0x58, 0x3a, 0xae, 0x74, 0xce, 0x32, 0x5c, 0x9d, 0x0b,
+  0x17, 0xef, 0x6a, 0x71, 0x7b, 0x64, 0x87, 0xb9, 0x46, 0xd3, 0xef, 0xfd,
+  0xa1, 0x86, 0xbc, 0x1c, 0xf2, 0x51, 0xee, 0x5f, 0xc6, 0x8a, 0x9f, 0xed,
+  0x9a, 0x94, 0x4e, 0xfb, 0x08, 0x6f, 0x34, 0x4a, 0xaf, 0x3d, 0x66, 0xcf,
+  0x48, 0xbc, 0xbb, 0x5e, 0xa1, 0xf7, 0x1b, 0x65, 0x56, 0x6a, 0x0c, 0x5e,
+  0x17, 0x22, 0xa4, 0x68, 0x59, 0x8e, 0x26, 0xb4, 0x01, 0x2b, 0x37, 0x27,
+  0xb1, 0x68, 0xc3, 0x1a, 0x81, 0x39, 0x6c, 0x3c, 0x81, 0xc1, 0xc3, 0xbb,
+  0x8f, 0xeb, 0x2e, 0xfc, 0xd6, 0x58, 0xad, 0xf4, 0x30, 0x6c, 0x7c, 0x93,
+  0x40, 0x15, 0x7a, 0x26, 0x03, 0x06, 0x9a, 0xa2, 0xd2, 0x7e, 0x88, 0xd0,
+  0x6a, 0x2c, 0x18, 0x37, 0x4a, 0x66, 0x48, 0xd4, 0xa1, 0x09, 0xff, 0x41,
+  0x1e, 0xd2, 0xe7, 0x6d, 0xb6, 0x11, 0xbf, 0xcd, 0x7a, 0x61, 0x0f, 0xc9,
+  0x59, 0x82, 0xc7, 0xf6, 0xd0, 0x74, 0x00, 0x7b, 0xa6, 0xd1, 0x7f, 0xb5,
+  0x6d, 0x84, 0xf4, 0xd4, 0xe4, 0x01, 0xf6, 0xd2, 0x6f, 0x8c, 0xfc, 0xf6,
+  0x1a, 0xfd, 0xae, 0xc5, 0x01, 0x97, 0xf0, 0xe7, 0xc7, 0x98, 0x16, 0xa3,
+  0xc4, 0x85, 0x3c, 0x86, 0xaa, 0xad, 0x94, 0x7e, 0x98, 0x21, 0x2b, 0xed,
+  0x7b, 0xab, 0x83, 0x20, 0xc0, 0xb6, 0x38, 0xe8, 0x7e, 0x60, 0xcf, 0x12,
+  0xf9, 0x50, 0xe6, 0xc1, 0x19, 0x20, 0x62, 0x74, 0xb8, 0x90, 0x37, 0xea,
+  0xfb, 0x11, 0x29, 0x98, 0x51, 0xc2, 0xeb, 0x14, 0xe0, 0x6d, 0x58, 0xb8,
+  0x9a, 0x46, 0xe7, 0xf9, 0x36, 0x91, 0xce, 0x67, 0xb3, 0xcc, 0x7c, 0xf9,
+  0x20, 0xae, 0x98, 0x49, 0x0d, 0x69, 0x2a, 0x3a, 0x69, 0xb1, 0x13, 0xe2,
+  0x07, 0x4e, 0xc8, 0x8f, 0x4b, 0xbc, 0x2e, 0x42, 0xf8, 0x69, 0x19, 0x62,
+  0x5a, 0x56, 0xe0, 0x46, 0x52, 0x16, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94,
+  0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03,
+  0x02, 0x01, 0x02, 0x02, 0x14, 0x38, 0x39, 0x6f, 0x5f, 0x80, 0x6d, 0xcf,
+  0xd1, 0x4e, 0x2f, 0x53, 0x68, 0x40, 0x42, 0xef, 0x69, 0xa1, 0xfe, 0x99,
+  0xf5, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
+  0x33, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31,
+  0x30, 0x32, 0x31, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36,
+  0x30, 0x39, 0x31, 0x30, 0x32, 0x31, 0x34, 0x34, 0x5a, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x33, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+  0x01, 0x01, 0x00, 0xc5, 0xa4, 0x45, 0xe2, 0xed, 0x42, 0x14, 0xcc, 0x23,
+  0x8f, 0x88, 0xd1, 0x25, 0xad, 0x09, 0xce, 0x76, 0x2a, 0xdf, 0x7f, 0xe5,
+  0x91, 0x68, 0x57, 0x47, 0xfc, 0xc0, 0x89, 0x58, 0xbe, 0x5d, 0xb8, 0xf0,
+  0x27, 0x14, 0xc6, 0x55, 0x1e, 0x77, 0xac, 0xdd, 0xa9, 0x68, 0x3b, 0x5d,
+  0x70, 0x8f, 0x46, 0x23, 0x79, 0x04, 0xaa, 0x4c, 0xac, 0x0b, 0x48, 0x34,
+  0x26, 0xf7, 0x17, 0xa3, 0x60, 0x99, 0x62, 0x20, 0x7f, 0x72, 0x28, 0x48,
+  0x1e, 0x7f, 0x80, 0x31, 0xd6, 0xd3, 0xa2, 0x5c, 0x96, 0xf1, 0x8d, 0x66,
+  0x1c, 0x68, 0x0e, 0x67, 0x17, 0x98, 0x75, 0xc1, 0x02, 0x8f, 0x9f, 0x6b,
+  0x7e, 0x56, 0x8c, 0xfc, 0x09, 0x93, 0xf8, 0xbb, 0x7e, 0x45, 0x8d, 0x29,
+  0x6c, 0xb3, 0xf1, 0x72, 0xf5, 0x51, 0xec, 0x89, 0xfa, 0x1f, 0xfb, 0x58,
+  0x48, 0x7b, 0x04, 0x4e, 0x28, 0xaf, 0x4a, 0xc4, 0x21, 0xc8, 0x4d, 0x16,
+  0x60, 0x7d, 0x56, 0x71, 0x9b, 0x56, 0x29, 0xaa, 0x31, 0xa1, 0x28, 0xa8,
+  0x6e, 0x6e, 0xfe, 0x02, 0xf8, 0x3b, 0x9a, 0xc6, 0xf2, 0xd1, 0x6c, 0xab,
+  0xaf, 0x75, 0xc8, 0xdb, 0xd6, 0x78, 0x66, 0x29, 0x78, 0x67, 0x65, 0x6c,
+  0x9d, 0x21, 0xb9, 0x3d, 0x7f, 0x72, 0x02, 0x8e, 0x00, 0x13, 0xe2, 0x13,
+  0x9f, 0xb8, 0x18, 0xe8, 0x61, 0x7c, 0x55, 0xd3, 0xa5, 0xd9, 0x93, 0x9f,
+  0x93, 0xed, 0x67, 0x5a, 0x1a, 0x1d, 0x01, 0x32, 0xfd, 0xcb, 0x26, 0xac,
+  0xfc, 0x89, 0x71, 0x4d, 0x8f, 0xf2, 0xfb, 0x04, 0xae, 0x0f, 0x8e, 0xbd,
+  0xdf, 0x7f, 0xb8, 0xe5, 0xcb, 0xc4, 0xd7, 0x7b, 0xfd, 0xa1, 0x70, 0x0b,
+  0xd3, 0xe3, 0xcf, 0xf1, 0x70, 0x0e, 0x50, 0xca, 0x54, 0x8c, 0xaf, 0xdc,
+  0xb2, 0x45, 0x82, 0xe4, 0xb6, 0xc7, 0x26, 0x2e, 0x7d, 0x8e, 0x2d, 0xc9,
+  0x2a, 0x22, 0x8e, 0x27, 0x07, 0x32, 0x51, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x95, 0x6e, 0xcf, 0x47, 0x75, 0x35, 0xd0, 0x19, 0xe5,
+  0x5a, 0x9a, 0xb0, 0x88, 0x48, 0xe0, 0xf4, 0xf4, 0x14, 0x3c, 0x85, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x95, 0x6e, 0xcf, 0x47, 0x75, 0x35, 0xd0, 0x19, 0xe5, 0x5a, 0x9a, 0xb0,
+  0x88, 0x48, 0xe0, 0xf4, 0xf4, 0x14, 0x3c, 0x85, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+  0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x86, 0xba, 0x2b,
+  0x96, 0x5e, 0x22, 0x2b, 0xef, 0x74, 0xc6, 0xf2, 0xbc, 0xbe, 0x21, 0xa8,
+  0x27, 0x2a, 0x17, 0x7c, 0xf9, 0xe5, 0xc4, 0x85, 0x15, 0x51, 0xaa, 0xe7,
+  0x2b, 0xe5, 0xda, 0xb6, 0xb4, 0x8f, 0xd3, 0xd1, 0x79, 0x19, 0xfb, 0x50,
+  0x82, 0x44, 0xfc, 0x43, 0xcd, 0xb5, 0x84, 0xa9, 0xfa, 0xe4, 0x46, 0xd3,
+  0x8b, 0x80, 0x5a, 0x7a, 0xb0, 0x2f, 0x13, 0x12, 0x26, 0xa9, 0xb6, 0x15,
+  0x8d, 0x15, 0x37, 0x6f, 0x1e, 0xd2, 0x40, 0xb1, 0xc4, 0x1e, 0x58, 0x92,
+  0xe8, 0xc8, 0x89, 0xe5, 0x1e, 0x5e, 0x2c, 0x55, 0xa9, 0x9e, 0x12, 0xab,
+  0x7c, 0x7b, 0x07, 0xa9, 0xc8, 0x02, 0x72, 0xc1, 0x14, 0xc6, 0x5e, 0xc8,
+  0xf9, 0xa8, 0x3f, 0xd4, 0x66, 0x97, 0x08, 0x34, 0x05, 0x36, 0x66, 0xcf,
+  0x6f, 0x06, 0x56, 0x56, 0x2b, 0xad, 0xb8, 0x13, 0x3f, 0xdb, 0x77, 0xd8,
+  0xd9, 0xf7, 0xb8, 0x12, 0x23, 0xbf, 0xda, 0x11, 0xd9, 0x7d, 0x1d, 0xdc,
+  0x38, 0xd4, 0x01, 0x43, 0x23, 0xea, 0xa4, 0x53, 0x75, 0x53, 0x06, 0xb5,
+  0xc9, 0xd5, 0x44, 0x9f, 0xbc, 0xd8, 0x31, 0xab, 0xb5, 0x5a, 0xb5, 0xbf,
+  0xd2, 0xf9, 0x2a, 0x39, 0xc9, 0x3c, 0x58, 0x7c, 0x50, 0x0e, 0x1d, 0x6e,
+  0x59, 0xf0, 0x94, 0x25, 0x16, 0x44, 0x6c, 0x07, 0x98, 0xc1, 0x02, 0xad,
+  0xb9, 0x1b, 0xac, 0x2f, 0x6b, 0x4a, 0xb3, 0x49, 0xd6, 0xfa, 0xa6, 0x71,
+  0xa4, 0xbc, 0x15, 0xec, 0x7f, 0x4e, 0x6e, 0xfd, 0x61, 0x43, 0x5b, 0xd9,
+  0x89, 0xc7, 0x7a, 0xed, 0xa2, 0x3a, 0x4b, 0x5a, 0x70, 0x82, 0x20, 0xb0,
+  0x98, 0x00, 0x01, 0x5d, 0xae, 0xb2, 0xcc, 0x52, 0xf3, 0x9e, 0x42, 0xc8,
+  0xc0, 0xb1, 0xb6, 0x7a, 0xa3, 0xf1, 0x67, 0xbd, 0x42, 0xdd, 0xa0, 0xda,
+  0x1f, 0x3d, 0xb7, 0xc1, 0x76, 0xfb, 0x3c, 0x4b, 0x5d, 0x16, 0x56, 0x9c,
+  0xc7
 };
-unsigned int PK3_auth_len = 2048;
+unsigned int PK3_auth_len = 2029;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/db1.h b/components/service/uefi/smm_variable/test/service/auth_vectors/db1.h
index 075b839..719e000 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/db1.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/db1.h
@@ -7,176 +7,175 @@
  */
 
 unsigned char DB1_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x3b, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x15, 0xc4, 0x07, 0x64, 0x88,
-  0x06, 0x82, 0x9c, 0x3c, 0x2d, 0x78, 0x10, 0xb2, 0xe0, 0xd2, 0x9e, 0x71,
-  0x1d, 0x2f, 0xa4, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x4b, 0x45, 0x4b, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
-  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x4b, 0x45, 0x4b, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xb1, 0x58, 0xde, 0xa8, 0xfb, 0xf9, 0xd2,
-  0x48, 0x11, 0x0a, 0x52, 0x68, 0xbf, 0x45, 0x97, 0xde, 0xdf, 0x54, 0xb3,
-  0x6e, 0x36, 0xc5, 0x3a, 0xbb, 0x40, 0x18, 0x66, 0xa7, 0x0e, 0x5d, 0xb1,
-  0x7a, 0x56, 0x24, 0xc7, 0x0d, 0x7e, 0x37, 0xba, 0x60, 0x6d, 0xf6, 0x81,
-  0x0a, 0x3d, 0x42, 0xec, 0x79, 0x49, 0x9a, 0x1c, 0x20, 0x08, 0x17, 0xc7,
-  0xba, 0x26, 0xc1, 0x71, 0x47, 0xc0, 0xe6, 0x29, 0xb8, 0xd0, 0x4f, 0xe9,
-  0xd2, 0x6f, 0x18, 0x49, 0x9d, 0xfc, 0x4a, 0xcc, 0x26, 0x74, 0xc6, 0x1e,
-  0xe7, 0x9c, 0x43, 0x2e, 0x09, 0xe0, 0x5a, 0x60, 0xa2, 0x27, 0xc0, 0x14,
-  0x32, 0x3d, 0xe4, 0x64, 0xf9, 0x25, 0x6b, 0x9c, 0x7a, 0x01, 0xea, 0xdf,
-  0x71, 0x26, 0xf8, 0x14, 0x89, 0xa0, 0x80, 0xf4, 0x8a, 0x05, 0x54, 0xc4,
-  0x9a, 0x7b, 0x32, 0x5e, 0x75, 0x0d, 0x1b, 0x8a, 0x38, 0x5c, 0x64, 0x7c,
-  0xf0, 0x65, 0x9e, 0xdf, 0x58, 0xaa, 0x71, 0xff, 0xc1, 0x20, 0xe1, 0x4b,
-  0x48, 0x68, 0x71, 0x4b, 0xfc, 0xef, 0x39, 0x8d, 0xae, 0x58, 0x97, 0x65,
-  0xb5, 0x44, 0x65, 0x33, 0x93, 0xa6, 0xc2, 0xf7, 0x3c, 0x23, 0x25, 0x47,
-  0x9c, 0x7b, 0xd8, 0x12, 0xbc, 0xba, 0xce, 0xfe, 0x07, 0xe1, 0xc2, 0x9a,
-  0x43, 0xb1, 0x09, 0x74, 0xea, 0xdd, 0x81, 0x9a, 0x66, 0xe9, 0x6f, 0x75,
-  0x8b, 0x63, 0x09, 0x9c, 0xf0, 0x85, 0x72, 0xe5, 0x2a, 0x9f, 0x3e, 0x03,
-  0xa2, 0x11, 0x73, 0xd5, 0xd0, 0x24, 0x59, 0x74, 0x10, 0x45, 0xcf, 0xe0,
-  0xb1, 0x3b, 0x35, 0x13, 0x92, 0x60, 0xba, 0x75, 0x1e, 0x39, 0xa2, 0x18,
-  0xb5, 0x23, 0xf6, 0xc1, 0x74, 0x5d, 0x73, 0x17, 0xea, 0xca, 0xdb, 0xc8,
-  0xc9, 0x9b, 0xf9, 0x83, 0x44, 0x29, 0x0d, 0xb2, 0xd1, 0x8e, 0x8f, 0xbb,
-  0xd4, 0x42, 0x43, 0x3d, 0xc1, 0x0f, 0xb0, 0x97, 0xaf, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0xe7, 0x8d, 0x45, 0x79, 0xdf, 0xb1, 0x92,
-  0x11, 0x72, 0x87, 0x8b, 0x78, 0xf8, 0xa7, 0x0a, 0x5b, 0x96, 0x87, 0x09,
-  0x5b, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0xe7, 0x8d, 0x45, 0x79, 0xdf, 0xb1, 0x92, 0x11, 0x72, 0x87,
-  0x8b, 0x78, 0xf8, 0xa7, 0x0a, 0x5b, 0x96, 0x87, 0x09, 0x5b, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x09,
-  0x51, 0x16, 0xf4, 0xd7, 0x79, 0xb5, 0xb7, 0x8b, 0x0d, 0x92, 0xc1, 0x9b,
-  0x0a, 0x19, 0x33, 0x4c, 0xf1, 0x00, 0x6a, 0xcd, 0x8f, 0xa5, 0xd0, 0x6e,
-  0x3e, 0x69, 0x35, 0x38, 0xb4, 0xb5, 0x44, 0x54, 0x36, 0x19, 0x58, 0xa8,
-  0xf4, 0x7e, 0xac, 0x8d, 0x41, 0x28, 0x79, 0x67, 0x7f, 0x0e, 0xbc, 0x6f,
-  0xa8, 0x96, 0x5c, 0x9e, 0xe3, 0x3f, 0x31, 0x4a, 0xa5, 0xb0, 0xfd, 0x1e,
-  0xbb, 0x0a, 0xc9, 0x53, 0x84, 0xf3, 0xa2, 0xe5, 0x1c, 0x80, 0x0a, 0xc5,
-  0x78, 0x5f, 0xe2, 0x52, 0xae, 0x36, 0x03, 0x98, 0x73, 0x3c, 0xb0, 0xf3,
-  0xd9, 0xc2, 0x95, 0x68, 0x03, 0xcd, 0xc7, 0x6b, 0x2f, 0x33, 0x38, 0xb5,
-  0x5a, 0x9b, 0xe7, 0x29, 0x23, 0xb1, 0x6c, 0xa2, 0x9e, 0x8d, 0xee, 0x85,
-  0x0d, 0x08, 0x16, 0xdd, 0x64, 0x56, 0x34, 0x81, 0xf1, 0x60, 0x9d, 0x2c,
-  0xed, 0x12, 0xb4, 0x9a, 0x75, 0xfe, 0xc1, 0x3e, 0x8c, 0xf1, 0x59, 0xbd,
-  0xf5, 0x35, 0xe2, 0xb6, 0x97, 0xaa, 0x57, 0x9b, 0xef, 0x1d, 0xf5, 0xd7,
-  0x81, 0x45, 0x41, 0x92, 0x6b, 0x68, 0x8c, 0xeb, 0x78, 0x3f, 0x9e, 0xff,
-  0x30, 0x4a, 0xd8, 0x84, 0x8d, 0x12, 0x4e, 0xbe, 0x2d, 0x87, 0xc4, 0x3a,
-  0xc6, 0x28, 0x10, 0x56, 0xab, 0x73, 0xce, 0xb4, 0xcc, 0xe6, 0x97, 0x77,
-  0xa9, 0x47, 0xa2, 0xd5, 0x05, 0x91, 0x2a, 0xcc, 0xe6, 0x0c, 0xf5, 0xd3,
-  0xb5, 0x97, 0xb3, 0x5a, 0x9e, 0xa1, 0x60, 0x1a, 0xfb, 0x11, 0x8b, 0xa8,
-  0x63, 0x4a, 0x2b, 0xc5, 0xb3, 0x4f, 0xff, 0xaf, 0x88, 0x15, 0x6c, 0xe7,
-  0xba, 0x19, 0x6a, 0xd3, 0xc3, 0xfd, 0x31, 0x96, 0x9c, 0x91, 0xba, 0xe9,
-  0xea, 0xf5, 0x60, 0xda, 0xe9, 0x11, 0xc7, 0x36, 0x2e, 0xf4, 0x1a, 0xde,
-  0x1a, 0xf7, 0x38, 0x9b, 0x68, 0xa2, 0x86, 0x1e, 0x34, 0x5d, 0x19, 0x9b,
-  0x82, 0x03, 0xe5, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4b, 0x45,
-  0x4b, 0x02, 0x14, 0x15, 0xc4, 0x07, 0x64, 0x88, 0x06, 0x82, 0x9c, 0x3c,
-  0x2d, 0x78, 0x10, 0xb2, 0xe0, 0xd2, 0x9e, 0x71, 0x1d, 0x2f, 0xa4, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x47, 0xe7, 0xa5,
-  0x3a, 0x03, 0xf1, 0x89, 0xa3, 0x23, 0x6e, 0xb5, 0xdb, 0xe3, 0x3a, 0x78,
-  0x5f, 0x8b, 0x69, 0x91, 0x1d, 0x7f, 0xc3, 0x74, 0x24, 0x2c, 0x10, 0xbc,
-  0xd0, 0xf1, 0x54, 0x14, 0xa7, 0xa3, 0x82, 0xe5, 0xc1, 0x04, 0x2a, 0xb6,
-  0x9e, 0x0d, 0xe2, 0x28, 0xbe, 0x7a, 0x3d, 0xe5, 0x25, 0x83, 0x6d, 0x85,
-  0x1a, 0x26, 0xcf, 0x5f, 0x1a, 0xa7, 0x57, 0x69, 0x91, 0xfd, 0xb7, 0x46,
-  0x33, 0x07, 0xae, 0x0a, 0xdb, 0x33, 0xc8, 0x23, 0x9a, 0x6e, 0xb9, 0x17,
-  0xd0, 0x77, 0x48, 0x24, 0xee, 0xc9, 0x92, 0x1d, 0x26, 0x3c, 0xe8, 0x26,
-  0x44, 0x90, 0x1c, 0xb9, 0x06, 0xc4, 0x93, 0x39, 0x57, 0x15, 0x65, 0xd1,
-  0xd5, 0x42, 0xb4, 0x8b, 0x91, 0xa3, 0xb8, 0xbb, 0x6f, 0x6b, 0xfe, 0x85,
-  0x89, 0xdc, 0x2e, 0xe7, 0x64, 0x7c, 0x43, 0x46, 0x33, 0x67, 0x9e, 0xf7,
-  0x46, 0x38, 0x8f, 0xe9, 0xe8, 0x82, 0x1d, 0xc6, 0x5a, 0xfe, 0x63, 0xad,
-  0xb4, 0xbe, 0xa6, 0x5d, 0x64, 0x60, 0x40, 0x93, 0x2f, 0xac, 0x88, 0xfc,
-  0x8d, 0x16, 0x50, 0xb9, 0x7e, 0xaa, 0x7d, 0xe2, 0x54, 0x49, 0xf6, 0x5e,
-  0xe2, 0x6d, 0x17, 0x4e, 0xf8, 0x6f, 0x6f, 0x58, 0xdc, 0x94, 0x9f, 0x2a,
-  0x31, 0x32, 0x17, 0x54, 0xb4, 0xd9, 0x86, 0x67, 0xf9, 0x05, 0xcd, 0x86,
-  0xfd, 0x69, 0x5a, 0xfc, 0x1f, 0x36, 0x48, 0x23, 0x6f, 0xf1, 0xf3, 0x91,
-  0x1f, 0x63, 0xff, 0x07, 0x65, 0x3e, 0xa3, 0x90, 0x4f, 0xdf, 0x21, 0x3b,
-  0xb2, 0x6e, 0x8a, 0x03, 0xce, 0x05, 0x0d, 0x95, 0x1f, 0x40, 0x00, 0x70,
-  0x0c, 0x53, 0x37, 0x0d, 0x03, 0x38, 0x18, 0x4a, 0xb7, 0xfb, 0x59, 0x43,
-  0xc2, 0x9f, 0xf7, 0xf4, 0x27, 0x9f, 0xed, 0x53, 0x22, 0xdf, 0x06, 0x52,
-  0x82, 0x3e, 0x1c, 0xec, 0xe3, 0x1d, 0xcb, 0x7d, 0xbd, 0xf6, 0x16, 0x48,
-  0x90, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab,
-  0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x03,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
   0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
-  0x2d, 0x56, 0x6b, 0xbb, 0xa5, 0x07, 0xa3, 0xa2, 0x44, 0x17, 0xca, 0x1c,
-  0xe2, 0xfc, 0xd3, 0x2e, 0x3c, 0x6b, 0x4b, 0x65, 0x30, 0x0d, 0x06, 0x09,
+  0x0c, 0x12, 0x5f, 0x58, 0xf0, 0xd3, 0x6a, 0x30, 0x85, 0x33, 0xc6, 0x78,
+  0x6c, 0xba, 0x96, 0x20, 0xfb, 0x14, 0x86, 0x6d, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42, 0x31, 0x30, 0x1e, 0x17, 0x0d,
-  0x32, 0x34, 0x30, 0x31, 0x32, 0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38,
-  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32,
-  0x30, 0x30, 0x38, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42,
-  0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x4b, 0x45, 0x4b, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x34, 0x35,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x34, 0x35, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x4b, 0x45,
+  0x4b, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
   0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
-  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xac, 0x13,
-  0xa9, 0xbb, 0x26, 0x22, 0x4c, 0x0f, 0xa9, 0x0a, 0x55, 0xbb, 0x40, 0x66,
-  0x73, 0xb2, 0x9f, 0x0e, 0x3a, 0xe8, 0x08, 0xce, 0xcd, 0x0d, 0x2b, 0xd9,
-  0xd1, 0x7e, 0x0b, 0x37, 0x6a, 0xf7, 0x7b, 0xb0, 0x21, 0x24, 0x61, 0x1d,
-  0xbb, 0x34, 0xb6, 0x28, 0x7b, 0xae, 0x77, 0x5b, 0x78, 0xab, 0x27, 0x5d,
-  0x65, 0xea, 0xe2, 0x8b, 0x89, 0x05, 0x2c, 0x61, 0xe6, 0x4d, 0x7b, 0x9f,
-  0xbc, 0xaa, 0x21, 0xff, 0x50, 0x86, 0x17, 0x7d, 0x41, 0x48, 0x80, 0xea,
-  0x60, 0x2c, 0xe9, 0x66, 0x20, 0x78, 0x84, 0xb6, 0x20, 0x1b, 0x47, 0xbd,
-  0x71, 0x26, 0x77, 0x4d, 0x41, 0x97, 0x65, 0x6b, 0x08, 0xcb, 0x68, 0xb5,
-  0xab, 0x73, 0x4a, 0xb8, 0x11, 0x60, 0x16, 0x3b, 0xc7, 0x34, 0x22, 0x01,
-  0xf7, 0x65, 0xbf, 0xf5, 0x8e, 0x3b, 0x93, 0xc4, 0x9f, 0xf5, 0xe8, 0xc2,
-  0x1f, 0xf9, 0x9d, 0xce, 0xf5, 0xa1, 0xe6, 0x60, 0x3c, 0xa6, 0xa7, 0xb6,
-  0xe3, 0xea, 0xc1, 0x18, 0x92, 0xde, 0x01, 0xe5, 0xbd, 0xf9, 0x9a, 0x8c,
-  0x39, 0x54, 0x67, 0x73, 0x57, 0xaa, 0x26, 0xce, 0x6f, 0x01, 0x7c, 0x29,
-  0xc1, 0xba, 0xf6, 0xad, 0x5f, 0x55, 0x12, 0x54, 0x65, 0xcd, 0xe6, 0xe5,
-  0x13, 0x4f, 0xf3, 0xc1, 0xed, 0xba, 0x1f, 0x32, 0x1a, 0x41, 0x02, 0xfe,
-  0x2b, 0x41, 0x07, 0xce, 0xc1, 0x69, 0x91, 0x93, 0xc8, 0x3d, 0x6d, 0x7c,
-  0xa8, 0xc8, 0xcb, 0xaa, 0x39, 0xf6, 0x59, 0x6f, 0x40, 0x48, 0xef, 0x16,
-  0xf7, 0xf3, 0xdf, 0xd5, 0xc2, 0x1a, 0xa6, 0xed, 0xff, 0x05, 0xa5, 0xac,
-  0x39, 0x32, 0x18, 0xcb, 0xe1, 0x87, 0x0f, 0xf8, 0x04, 0x55, 0x50, 0xb7,
-  0xfb, 0xa2, 0xa2, 0x05, 0x33, 0xa5, 0x15, 0x46, 0xd8, 0x14, 0x35, 0xd2,
-  0x08, 0x14, 0x48, 0x15, 0x45, 0x0a, 0x7d, 0xfd, 0xa5, 0x36, 0x7e, 0xd4,
-  0x23, 0xb9, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
-  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x28, 0x8e,
-  0x10, 0x73, 0x79, 0x18, 0xac, 0xe1, 0xfc, 0xd1, 0x85, 0x96, 0x35, 0x62,
-  0xc3, 0x6c, 0xff, 0x30, 0x20, 0xcc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
-  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x28, 0x8e, 0x10, 0x73, 0x79,
-  0x18, 0xac, 0xe1, 0xfc, 0xd1, 0x85, 0x96, 0x35, 0x62, 0xc3, 0x6c, 0xff,
-  0x30, 0x20, 0xcc, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc0, 0x81,
+  0x99, 0xa7, 0xb3, 0xc2, 0xbb, 0x60, 0xb5, 0x3a, 0x4d, 0x56, 0x24, 0xbe,
+  0xcf, 0xd6, 0x93, 0x58, 0xba, 0xc4, 0x6d, 0x7a, 0x7a, 0x40, 0xeb, 0xcc,
+  0x19, 0x03, 0x10, 0x18, 0xaf, 0x50, 0x59, 0xdd, 0x2e, 0x08, 0x04, 0x07,
+  0xc8, 0x54, 0x6d, 0x39, 0xf9, 0x64, 0x50, 0xe3, 0x56, 0x30, 0x72, 0xe6,
+  0x2c, 0x00, 0xea, 0x0e, 0xa6, 0x34, 0x8f, 0x45, 0x36, 0xe7, 0x50, 0x66,
+  0xe1, 0x48, 0xb3, 0x15, 0x44, 0x80, 0x19, 0x0c, 0x0a, 0x39, 0x79, 0x81,
+  0x77, 0xe3, 0x4f, 0x2e, 0xdb, 0x9a, 0xbe, 0xdc, 0xa8, 0xf4, 0x68, 0xc2,
+  0xdc, 0x2d, 0x82, 0x6c, 0x9a, 0xd0, 0x5b, 0xc5, 0xe6, 0x6b, 0x8d, 0x47,
+  0xe0, 0xa1, 0x1a, 0x60, 0x77, 0x5e, 0x43, 0x07, 0x54, 0xd8, 0xf4, 0xa6,
+  0x39, 0x05, 0x81, 0x81, 0xf4, 0xae, 0xeb, 0xa2, 0x3b, 0x10, 0xfa, 0x4d,
+  0xfe, 0x36, 0x8c, 0x97, 0x63, 0xd9, 0x5a, 0xac, 0xb3, 0xb3, 0x00, 0x92,
+  0x05, 0x2b, 0x40, 0x1e, 0x19, 0x82, 0x95, 0x88, 0xc1, 0x12, 0x8b, 0x75,
+  0xd0, 0x2e, 0x7d, 0xff, 0xaa, 0xfa, 0x42, 0x06, 0x65, 0xe4, 0xf6, 0x53,
+  0xc5, 0xfc, 0x27, 0xc7, 0xa5, 0x7e, 0x53, 0x16, 0x14, 0xb4, 0xc1, 0x0d,
+  0xb0, 0xe2, 0x68, 0x7b, 0x4f, 0x12, 0x73, 0x8e, 0x83, 0xde, 0x87, 0xd7,
+  0xa4, 0xa5, 0x89, 0x47, 0xc8, 0x0c, 0xfc, 0x97, 0xe3, 0x7f, 0xac, 0x9a,
+  0x0e, 0x6d, 0xb0, 0x30, 0x81, 0xf5, 0x44, 0x30, 0x9f, 0xf1, 0x35, 0x74,
+  0x9a, 0xd6, 0xa9, 0x3f, 0x7b, 0xda, 0xb6, 0x6c, 0x57, 0xf3, 0x30, 0x79,
+  0x28, 0xf1, 0x80, 0x59, 0x74, 0x89, 0x8e, 0x47, 0xdb, 0x18, 0x88, 0xcc,
+  0x70, 0xe8, 0x83, 0xc9, 0x71, 0x4a, 0x98, 0x70, 0x59, 0x75, 0xb6, 0xc0,
+  0x38, 0x4c, 0x99, 0xd6, 0xcf, 0x7d, 0xa5, 0x7e, 0x31, 0x0c, 0x2c, 0xec,
+  0x40, 0x33, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa3, 0xa7,
+  0xec, 0x3a, 0x10, 0xec, 0x88, 0xfd, 0x73, 0x14, 0x02, 0xf7, 0x0d, 0x93,
+  0x72, 0x23, 0xdb, 0x2b, 0x6d, 0xd3, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xa3, 0xa7, 0xec, 0x3a, 0x10,
+  0xec, 0x88, 0xfd, 0x73, 0x14, 0x02, 0xf7, 0x0d, 0x93, 0x72, 0x23, 0xdb,
+  0x2b, 0x6d, 0xd3, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
   0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
-  0x82, 0x01, 0x01, 0x00, 0x4a, 0x19, 0x4b, 0x7a, 0xe2, 0x4c, 0xbb, 0x7a,
-  0xde, 0x38, 0xc0, 0xd2, 0x45, 0x8a, 0x18, 0x9e, 0x80, 0xfa, 0xfb, 0xed,
-  0x97, 0x0d, 0x29, 0x7a, 0xf3, 0x52, 0xc4, 0xc5, 0xfa, 0x57, 0x0b, 0x63,
-  0xf5, 0x7b, 0x45, 0x11, 0x7c, 0xed, 0x3e, 0xa1, 0x40, 0xd3, 0xef, 0x51,
-  0xb8, 0x18, 0x31, 0xba, 0xa4, 0x7f, 0x1f, 0x95, 0x3b, 0xd4, 0xae, 0x89,
-  0x47, 0xf2, 0x40, 0xa3, 0x04, 0x20, 0x31, 0x55, 0xb7, 0xf7, 0xcd, 0x05,
-  0x2b, 0x2c, 0xca, 0x55, 0xa6, 0xed, 0x0e, 0x84, 0x43, 0xfb, 0xcd, 0x22,
-  0xeb, 0xb9, 0x1e, 0xd4, 0x36, 0x49, 0x14, 0xcf, 0xa6, 0x75, 0x53, 0x1a,
-  0x9b, 0x64, 0x05, 0x18, 0x23, 0xa4, 0x4e, 0xb1, 0x95, 0x24, 0x07, 0xce,
-  0xca, 0x79, 0x57, 0x3a, 0x7f, 0xd6, 0x02, 0x3e, 0xf7, 0x7a, 0xde, 0x68,
-  0xd1, 0x5c, 0xc0, 0xbd, 0x60, 0xed, 0x56, 0xf5, 0x9f, 0xa1, 0x94, 0x68,
-  0x39, 0xa6, 0x9b, 0x9d, 0xdf, 0x98, 0x4a, 0x34, 0x39, 0xcc, 0xd5, 0x38,
-  0xc8, 0x2e, 0x66, 0x69, 0xaf, 0x6d, 0x46, 0xc8, 0x52, 0xc4, 0x9e, 0x9f,
-  0xe6, 0x4f, 0xa9, 0xd2, 0xf5, 0x15, 0x9a, 0xa1, 0xaa, 0xab, 0x09, 0x67,
-  0x76, 0x62, 0x6c, 0x5c, 0xf8, 0x1b, 0x4c, 0x57, 0x77, 0x53, 0x2c, 0xe0,
-  0x91, 0x8b, 0x63, 0xd3, 0xd0, 0xd4, 0xad, 0x89, 0x6c, 0x3d, 0xe2, 0x9a,
-  0xe2, 0x75, 0xf5, 0x33, 0xd3, 0x74, 0x1e, 0xd6, 0xd0, 0x5c, 0x41, 0x3e,
-  0xa2, 0x14, 0x04, 0x90, 0xde, 0xfd, 0x68, 0x5d, 0xbd, 0x87, 0x4f, 0x6c,
-  0x00, 0xae, 0x94, 0xa4, 0xf0, 0x8b, 0xb4, 0x29, 0x58, 0xd8, 0xd0, 0x9c,
-  0xa6, 0xd3, 0x62, 0x47, 0xee, 0x8c, 0xf6, 0xeb, 0xe9, 0x99, 0x86, 0x45,
-  0x55, 0xd7, 0x91, 0xc9, 0xe6, 0xcb, 0x2e, 0xa2, 0x63, 0x16, 0xc9, 0x30,
-  0xdf, 0x72, 0x59, 0x06, 0xe8, 0x22, 0x6b, 0xda
+  0x82, 0x01, 0x01, 0x00, 0xa8, 0x34, 0xda, 0xa3, 0xda, 0x94, 0xda, 0xcf,
+  0xde, 0x1d, 0x83, 0xa2, 0x0f, 0x94, 0x15, 0xae, 0x1f, 0xda, 0x68, 0xa4,
+  0x42, 0x3c, 0xac, 0x7e, 0xff, 0x08, 0x05, 0x32, 0x5e, 0x08, 0x0d, 0xd9,
+  0x3d, 0xbe, 0x06, 0xf2, 0xa7, 0xd7, 0xef, 0xe2, 0xf5, 0xbc, 0x83, 0x6b,
+  0x18, 0x50, 0xe0, 0x16, 0xe6, 0xe9, 0x99, 0x19, 0xd3, 0xd5, 0xae, 0x48,
+  0x42, 0x59, 0x86, 0x0b, 0xa0, 0xee, 0x0c, 0xdb, 0x74, 0xc2, 0xe3, 0x37,
+  0xc5, 0xd3, 0xa8, 0xba, 0xcf, 0x93, 0x3d, 0xb5, 0x49, 0x1e, 0x45, 0xd7,
+  0x58, 0xa1, 0x82, 0xbd, 0xa7, 0x9a, 0x56, 0x9b, 0x34, 0x16, 0x96, 0xac,
+  0xa1, 0xfe, 0xe4, 0xff, 0x32, 0x4b, 0x69, 0xd9, 0x2c, 0xa8, 0x6a, 0xbd,
+  0x96, 0xf4, 0xc6, 0x4d, 0xb6, 0x43, 0xfd, 0x06, 0xab, 0xf4, 0xb4, 0x77,
+  0xae, 0xfe, 0x1b, 0x5d, 0x50, 0x8b, 0x75, 0x7e, 0xc6, 0xe2, 0x72, 0x1c,
+  0x0f, 0x1f, 0x7a, 0x0c, 0xdd, 0x55, 0xc4, 0x31, 0x57, 0x9d, 0xc0, 0x27,
+  0x36, 0xb5, 0x2c, 0xeb, 0xb6, 0xd7, 0xd5, 0xee, 0x68, 0x6b, 0xdf, 0xf4,
+  0xaa, 0x42, 0xd7, 0xf4, 0x65, 0x97, 0x94, 0xd8, 0x4a, 0x0c, 0xa8, 0xda,
+  0xcc, 0xe9, 0xc1, 0xd5, 0x83, 0x41, 0xcd, 0xb2, 0x26, 0xbe, 0x7b, 0xbe,
+  0x7b, 0x8e, 0x07, 0x32, 0x56, 0x44, 0xa4, 0xaf, 0xf0, 0xca, 0xb5, 0x27,
+  0xfa, 0xa5, 0x6e, 0x1b, 0x9c, 0xcd, 0x5c, 0x4e, 0xd8, 0x36, 0xd2, 0x3d,
+  0xa3, 0x80, 0x40, 0x66, 0x69, 0x46, 0x7e, 0x88, 0xd5, 0x3d, 0x11, 0x84,
+  0x85, 0x6b, 0x97, 0xd2, 0x26, 0x4c, 0x20, 0x3d, 0xb1, 0xee, 0x3e, 0x36,
+  0x8b, 0xd1, 0x37, 0xa7, 0xb3, 0x79, 0x5c, 0xef, 0x7b, 0x69, 0x18, 0xdc,
+  0xcd, 0x8a, 0xbb, 0x1c, 0x53, 0x1f, 0x9b, 0xa8, 0x3c, 0xfa, 0x89, 0xc0,
+  0x16, 0xa2, 0x0a, 0xb0, 0x2b, 0xcd, 0x03, 0x13, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x4b, 0x45, 0x4b, 0x02, 0x14, 0x0c, 0x12, 0x5f, 0x58,
+  0xf0, 0xd3, 0x6a, 0x30, 0x85, 0x33, 0xc6, 0x78, 0x6c, 0xba, 0x96, 0x20,
+  0xfb, 0x14, 0x86, 0x6d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x2d, 0xfe, 0x3a, 0x45, 0x4c, 0x00, 0x1b, 0x68, 0xe8, 0x04,
+  0x21, 0x4a, 0x51, 0xe0, 0x7c, 0x55, 0x09, 0x7e, 0xf0, 0x00, 0xbc, 0x0c,
+  0x97, 0x54, 0xb1, 0xa7, 0xd6, 0xa0, 0x07, 0x35, 0xa5, 0x2d, 0x4a, 0xd9,
+  0xe7, 0xf8, 0x56, 0x63, 0xd1, 0x2e, 0x67, 0xc8, 0x05, 0xb8, 0x69, 0x05,
+  0xa8, 0x13, 0x59, 0x0b, 0xcd, 0xe0, 0x64, 0x31, 0xcc, 0xfd, 0x2b, 0xb0,
+  0xda, 0x03, 0xb0, 0x16, 0xed, 0xac, 0xe9, 0xf0, 0x57, 0xea, 0x0f, 0xdb,
+  0xf1, 0xfa, 0x86, 0xa3, 0x55, 0xc8, 0x8e, 0xbd, 0xd7, 0xd0, 0x97, 0x9d,
+  0xf5, 0xda, 0xf1, 0x28, 0x0d, 0xf4, 0x6c, 0xab, 0xee, 0xbe, 0x98, 0xb0,
+  0x38, 0xbc, 0xdb, 0x11, 0x26, 0x93, 0xcd, 0x67, 0xf1, 0x90, 0x72, 0x42,
+  0xca, 0x0a, 0xa2, 0xa4, 0x3f, 0x14, 0xdf, 0x1d, 0x00, 0x88, 0xd3, 0x21,
+  0x8d, 0x65, 0x5d, 0x32, 0xa9, 0x16, 0x6c, 0xb3, 0xfb, 0x17, 0xbf, 0xfd,
+  0x6a, 0x0a, 0xd4, 0x99, 0x9b, 0xe3, 0xda, 0xab, 0x6d, 0x5c, 0x3e, 0xc5,
+  0x99, 0xe5, 0xb6, 0xa8, 0xff, 0x32, 0x33, 0xdf, 0x64, 0x33, 0x3c, 0xb5,
+  0x2b, 0x8d, 0x5a, 0x62, 0xfa, 0x45, 0x11, 0xab, 0xab, 0xf2, 0x29, 0x8e,
+  0xb5, 0xd9, 0x62, 0x64, 0x8e, 0x47, 0xac, 0xcd, 0xfc, 0xfb, 0xed, 0x2e,
+  0x6e, 0x39, 0x2b, 0x12, 0x1a, 0x84, 0x90, 0x45, 0xf2, 0x92, 0x85, 0xbe,
+  0x48, 0x89, 0x45, 0xbc, 0xb6, 0x72, 0xc1, 0x3f, 0x15, 0xc5, 0x32, 0x7a,
+  0x98, 0xf9, 0xe2, 0x8c, 0x4f, 0x97, 0x8c, 0x1a, 0xcf, 0xa7, 0x9b, 0x19,
+  0x14, 0x67, 0xc1, 0x13, 0xbe, 0x4f, 0x29, 0xc0, 0x78, 0x05, 0xeb, 0xeb,
+  0x2c, 0x2c, 0x5a, 0xa8, 0x9d, 0x09, 0x26, 0x2a, 0x02, 0xc3, 0x6d, 0x48,
+  0x90, 0x8e, 0x1d, 0xf4, 0x82, 0xde, 0x6d, 0xc8, 0xf8, 0x87, 0x0e, 0x79,
+  0x2b, 0x21, 0x37, 0x48, 0x2a, 0x82, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94,
+  0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03,
+  0x02, 0x01, 0x02, 0x02, 0x14, 0x18, 0x5b, 0xb8, 0x4b, 0x5a, 0xdf, 0xdb,
+  0x63, 0x0d, 0x88, 0xea, 0x94, 0xfa, 0xe9, 0x4a, 0xc0, 0x1e, 0xb0, 0x57,
+  0xca, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42,
+  0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31,
+  0x30, 0x32, 0x31, 0x34, 0x37, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36,
+  0x30, 0x39, 0x31, 0x30, 0x32, 0x31, 0x34, 0x37, 0x5a, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x44, 0x42, 0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+  0x01, 0x01, 0x00, 0xd2, 0xf8, 0xbe, 0xd5, 0xb4, 0xbb, 0x24, 0x09, 0x98,
+  0x84, 0xbc, 0x3c, 0x34, 0x28, 0xed, 0xed, 0xe3, 0xd4, 0xad, 0x87, 0xdd,
+  0x92, 0x44, 0x16, 0x22, 0xc7, 0xc7, 0xf1, 0x54, 0x3c, 0x27, 0xf3, 0x9d,
+  0xe2, 0x34, 0x39, 0x3a, 0x41, 0x14, 0x0e, 0xfb, 0xf5, 0xce, 0x89, 0x6b,
+  0x4a, 0x07, 0xc7, 0x94, 0xa6, 0x8c, 0xd4, 0x0e, 0x41, 0xaa, 0x63, 0xf1,
+  0x83, 0x12, 0x90, 0x0c, 0x70, 0x1e, 0xb3, 0x3c, 0x5f, 0x0b, 0xc1, 0xba,
+  0x06, 0x8c, 0x93, 0x39, 0xc0, 0xfa, 0x65, 0x84, 0xd6, 0x65, 0x53, 0xf6,
+  0x47, 0x2a, 0x3b, 0xe2, 0x42, 0x49, 0x33, 0x47, 0xff, 0x37, 0xfb, 0x60,
+  0xb3, 0xac, 0xc6, 0xee, 0x91, 0x67, 0xc0, 0x32, 0xb6, 0xf7, 0xe0, 0xcb,
+  0xb8, 0xf2, 0x28, 0x34, 0x3e, 0x3f, 0x4b, 0x80, 0xd2, 0xb7, 0xce, 0xc0,
+  0x25, 0xae, 0xbc, 0x4f, 0x33, 0xa9, 0xf2, 0xd2, 0x33, 0x79, 0xca, 0x89,
+  0x00, 0xa9, 0x51, 0x38, 0x12, 0xb6, 0x0e, 0x18, 0x6f, 0x36, 0xa0, 0x20,
+  0x9d, 0xfa, 0xdd, 0xf7, 0xb9, 0x1b, 0x0f, 0x75, 0x47, 0x6d, 0xb7, 0x98,
+  0x17, 0x3c, 0x05, 0xbc, 0xe3, 0xec, 0x05, 0x09, 0x99, 0x4b, 0xfc, 0xce,
+  0xea, 0xf2, 0xee, 0x1c, 0x0b, 0x18, 0xb5, 0x8c, 0x18, 0xbb, 0xa5, 0x8f,
+  0xaf, 0x5c, 0xab, 0x49, 0xca, 0x4f, 0xa6, 0x7a, 0x33, 0x99, 0xba, 0x31,
+  0x5d, 0xb4, 0xb2, 0x25, 0x93, 0x59, 0x29, 0x29, 0xb6, 0xa7, 0x29, 0xd5,
+  0x4e, 0x95, 0xa6, 0x63, 0x60, 0x43, 0xdd, 0x0b, 0xc4, 0xb4, 0xb2, 0xb7,
+  0x36, 0xb6, 0xe9, 0xd9, 0xb4, 0x94, 0x44, 0xfe, 0xde, 0x0f, 0xcd, 0x04,
+  0xb7, 0x02, 0x16, 0xd3, 0x24, 0xe0, 0x85, 0xb9, 0xba, 0x2b, 0xaf, 0x07,
+  0x88, 0x56, 0x6a, 0xd9, 0x40, 0x58, 0x23, 0x50, 0x8d, 0xaf, 0x71, 0x67,
+  0x93, 0x6d, 0xed, 0x49, 0xa7, 0xbd, 0x11, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x6c, 0x04, 0xf9, 0x87, 0xa0, 0xaf, 0x12, 0x1e, 0xd5,
+  0x29, 0xdc, 0x65, 0x0e, 0x0a, 0x86, 0x83, 0xfd, 0xd5, 0xf8, 0x80, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x6c, 0x04, 0xf9, 0x87, 0xa0, 0xaf, 0x12, 0x1e, 0xd5, 0x29, 0xdc, 0x65,
+  0x0e, 0x0a, 0x86, 0x83, 0xfd, 0xd5, 0xf8, 0x80, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+  0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xc3, 0x50, 0x01,
+  0x9e, 0x6c, 0x9f, 0xcc, 0xb4, 0x25, 0xb1, 0x67, 0x33, 0x2c, 0xf2, 0x0d,
+  0x6a, 0x69, 0xb2, 0xd8, 0x33, 0xbc, 0x04, 0x3e, 0xac, 0x0a, 0x86, 0x0d,
+  0x23, 0xcb, 0x2c, 0x18, 0x40, 0xbb, 0xc3, 0x45, 0x03, 0xef, 0xb7, 0x1a,
+  0x99, 0x1b, 0x74, 0x20, 0xf4, 0xd1, 0x60, 0x9c, 0x11, 0xb7, 0xb8, 0x6c,
+  0x2a, 0xe8, 0xf4, 0x0b, 0x47, 0x55, 0xb3, 0x9b, 0x2e, 0x16, 0xcc, 0xef,
+  0x05, 0xda, 0x5c, 0xa7, 0x25, 0x8b, 0x37, 0xea, 0x53, 0x0b, 0xd7, 0x2a,
+  0x9e, 0x0d, 0x34, 0xca, 0x9c, 0x86, 0x8b, 0x48, 0xe0, 0xe8, 0xef, 0x32,
+  0x06, 0xb7, 0xd1, 0xb5, 0x37, 0x6c, 0x43, 0x5a, 0x1c, 0x57, 0x41, 0x64,
+  0x65, 0x48, 0xdc, 0x06, 0x9a, 0x58, 0x74, 0x61, 0xed, 0x6d, 0xe9, 0xf7,
+  0x10, 0xb6, 0x2a, 0x2e, 0xbe, 0x87, 0x68, 0x2a, 0xd7, 0xff, 0xe2, 0x37,
+  0x7a, 0x65, 0xf5, 0x20, 0x51, 0xb1, 0xf4, 0x18, 0x2f, 0x24, 0xf5, 0xc0,
+  0x78, 0xbb, 0x70, 0xee, 0xf8, 0xe2, 0x01, 0x7a, 0xbb, 0x57, 0x9b, 0xc4,
+  0x28, 0x5c, 0x2b, 0x8f, 0xe0, 0xec, 0x90, 0xf6, 0x98, 0x4f, 0xee, 0x30,
+  0x5e, 0x02, 0x6a, 0x0b, 0xa3, 0x45, 0xbf, 0x24, 0x81, 0x75, 0x2a, 0x0e,
+  0x34, 0x06, 0x0a, 0x3a, 0x0d, 0x83, 0xf3, 0x25, 0x1a, 0x34, 0x71, 0x61,
+  0xe0, 0x79, 0xc8, 0xc5, 0x9a, 0xab, 0x44, 0x93, 0x60, 0x43, 0x73, 0x4f,
+  0xb9, 0x45, 0xdd, 0x64, 0x4d, 0x79, 0xf2, 0x9d, 0xb0, 0x36, 0x63, 0x6c,
+  0xd0, 0x3d, 0x01, 0x79, 0x04, 0xe0, 0x03, 0xe5, 0x61, 0x5d, 0xe5, 0x97,
+  0x34, 0x0b, 0x00, 0x58, 0x9a, 0x23, 0xc3, 0xea, 0xe6, 0xc1, 0x43, 0x6c,
+  0x6a, 0x1b, 0xc7, 0xa4, 0xed, 0xfb, 0x50, 0xda, 0xa3, 0x20, 0xa6, 0x79,
+  0x6c, 0x77, 0x02, 0x6d, 0xd4, 0x69, 0xee, 0x4b, 0x5f, 0x08, 0x79, 0x1e,
+  0x3d
 };
-unsigned int DB1_auth_len = 2048;
+unsigned int DB1_auth_len = 2029;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/db2.h b/components/service/uefi/smm_variable/test/service/auth_vectors/db2.h
index 0e7a5f6..d8f97ce 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/db2.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/db2.h
@@ -7,176 +7,175 @@
  */
 
 unsigned char DB2_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x15, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0,
-  0x7a, 0xa6, 0xe6, 0x9b, 0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b,
-  0xc7, 0xa8, 0x37, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
-  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xcb, 0x94, 0x4f, 0x33, 0x47, 0xe3, 0xb3,
-  0xd0, 0x34, 0x45, 0x48, 0xea, 0x6c, 0x66, 0x8d, 0xb0, 0x97, 0x41, 0xe8,
-  0x81, 0x7f, 0xab, 0x83, 0xa5, 0x9f, 0xa6, 0x5d, 0x47, 0x9b, 0x60, 0x55,
-  0xc3, 0x70, 0x2c, 0xf5, 0x96, 0x9f, 0xa8, 0xdb, 0xc0, 0xca, 0x63, 0x7c,
-  0x34, 0xed, 0x14, 0x9e, 0xc0, 0xbe, 0xab, 0xe4, 0x3b, 0x73, 0xed, 0x62,
-  0x24, 0xe8, 0x68, 0xa4, 0x14, 0x10, 0x50, 0x8f, 0x7f, 0x59, 0xad, 0xec,
-  0x16, 0x60, 0xfe, 0x1f, 0x60, 0x3b, 0x9a, 0x7b, 0x7a, 0xc3, 0x3e, 0xf4,
-  0xcf, 0x39, 0x27, 0x70, 0xb9, 0xd9, 0x0a, 0x40, 0xc7, 0x7f, 0x41, 0x80,
-  0xd3, 0xe0, 0x22, 0x15, 0x1a, 0x91, 0x0e, 0x4a, 0xa7, 0x52, 0x33, 0x72,
-  0xf2, 0x46, 0x03, 0x42, 0x36, 0x85, 0x27, 0xf0, 0x2f, 0x9f, 0x56, 0xa4,
-  0xd5, 0xdc, 0x00, 0xd5, 0x5e, 0xe5, 0x1a, 0x08, 0xae, 0xdc, 0x80, 0xb9,
-  0xa4, 0xcf, 0x58, 0xf1, 0xd4, 0x38, 0x5f, 0xe1, 0xff, 0x81, 0x01, 0xff,
-  0x17, 0x77, 0xe7, 0x4b, 0xee, 0x91, 0xaf, 0x3a, 0xf9, 0x73, 0xd9, 0x6f,
-  0xe9, 0x22, 0x55, 0x15, 0x17, 0xa9, 0xc9, 0xde, 0xfc, 0x63, 0xfc, 0x84,
-  0x96, 0xb7, 0xf8, 0x40, 0x63, 0x5f, 0x2c, 0x21, 0x20, 0x1e, 0x37, 0x14,
-  0x1b, 0x4e, 0x76, 0xec, 0x3a, 0xcb, 0xd5, 0xdc, 0xef, 0x96, 0x37, 0x43,
-  0x46, 0x4c, 0x2e, 0xf4, 0xcb, 0x58, 0x90, 0x91, 0x35, 0x6d, 0xb5, 0x58,
-  0xb8, 0xb7, 0x74, 0x72, 0x80, 0x3f, 0xb7, 0xd0, 0x1b, 0xca, 0x47, 0x18,
-  0xc9, 0x99, 0x4d, 0x74, 0x97, 0x57, 0xc4, 0x2f, 0x2e, 0x2a, 0xd0, 0x95,
-  0xc2, 0x1e, 0x64, 0x8d, 0xbd, 0xd1, 0x7e, 0xf6, 0x6c, 0x44, 0x01, 0x1f,
-  0x37, 0xc0, 0x67, 0x7a, 0x78, 0x47, 0x21, 0xb4, 0x0d, 0xc6, 0xab, 0x81,
-  0x7e, 0x1c, 0x10, 0x5d, 0x01, 0x2e, 0xfe, 0x41, 0x93, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4,
-  0xbb, 0x06, 0xa7, 0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66,
-  0x08, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x18, 0x51, 0xee, 0x40, 0x22, 0xae, 0xa4, 0xbb, 0x06, 0xa7,
-  0xf2, 0xb0, 0x08, 0xf9, 0x5e, 0x89, 0x08, 0x08, 0x66, 0x08, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x3a,
-  0xae, 0xa0, 0xfa, 0x34, 0x4a, 0x52, 0x24, 0x90, 0x3a, 0xba, 0x33, 0x61,
-  0x0f, 0xc8, 0x6f, 0xbc, 0x72, 0xf8, 0xc3, 0x98, 0x04, 0xe1, 0xcb, 0xf2,
-  0x82, 0xfd, 0x83, 0x59, 0x51, 0x23, 0x71, 0xf4, 0xce, 0xe9, 0x36, 0x4d,
-  0x0a, 0xd3, 0x11, 0x6d, 0x51, 0xb7, 0xd1, 0x9f, 0x9b, 0x85, 0x5c, 0x25,
-  0x11, 0x9c, 0x13, 0xf6, 0x33, 0xd8, 0xa4, 0x27, 0xef, 0x90, 0x56, 0x21,
-  0xe3, 0x90, 0x10, 0x2b, 0x50, 0x46, 0x6e, 0x8a, 0x84, 0x3e, 0x30, 0x4c,
-  0xc2, 0xdf, 0x81, 0x60, 0xdf, 0xb8, 0x06, 0xd8, 0x2f, 0xcf, 0x3f, 0xb8,
-  0xbe, 0x04, 0xa4, 0xbb, 0xba, 0x65, 0x9f, 0x4e, 0xc4, 0x05, 0xbe, 0x9e,
-  0xfe, 0xa9, 0x0c, 0x06, 0x81, 0xcc, 0xa4, 0x66, 0xb0, 0x14, 0x48, 0xc9,
-  0x24, 0x88, 0xd8, 0xdc, 0xf2, 0x5c, 0xb5, 0x59, 0x66, 0x4f, 0xc6, 0xa4,
-  0xa3, 0x96, 0xa8, 0x48, 0x3b, 0x43, 0xff, 0xe0, 0x10, 0x53, 0x79, 0x47,
-  0x74, 0xe8, 0xbc, 0xa9, 0x4f, 0x8e, 0x1f, 0xfb, 0xf8, 0xad, 0x8d, 0x10,
-  0x80, 0x8f, 0x80, 0xf8, 0x5b, 0x36, 0xff, 0x60, 0x0b, 0x3f, 0xb2, 0x2f,
-  0x46, 0x27, 0x43, 0x00, 0x1a, 0x0d, 0xb8, 0x91, 0x4e, 0x84, 0xb1, 0x94,
-  0xc2, 0xca, 0xd6, 0x36, 0x4d, 0xc6, 0xda, 0x53, 0x71, 0xcc, 0xc8, 0x8e,
-  0x9c, 0xdb, 0x31, 0xbb, 0x93, 0x49, 0xa7, 0xf4, 0x0b, 0x19, 0xcb, 0xaa,
-  0x2b, 0x0c, 0xf4, 0xc7, 0x59, 0x8a, 0xc6, 0x59, 0x0b, 0x1d, 0x2f, 0xc3,
-  0xcf, 0x06, 0xcf, 0x2e, 0x6b, 0x15, 0x6f, 0xba, 0xd1, 0xfa, 0x7d, 0x7f,
-  0xaa, 0x99, 0x09, 0x63, 0xa8, 0xdd, 0x6c, 0xdb, 0x6a, 0x5e, 0x00, 0x5e,
-  0x89, 0x11, 0xe3, 0xbd, 0xf6, 0xcb, 0x13, 0x89, 0x6a, 0xb8, 0x7e, 0x89,
-  0xbc, 0xa5, 0xec, 0x68, 0x85, 0xf0, 0xaa, 0x05, 0x91, 0xc1, 0x79, 0xa1,
-  0x1c, 0x9d, 0x32, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
-  0x31, 0x02, 0x14, 0x71, 0x90, 0xc6, 0x30, 0xd0, 0x7a, 0xa6, 0xe6, 0x9b,
-  0x3f, 0x3b, 0x01, 0x47, 0x16, 0xad, 0x20, 0x9b, 0xc7, 0xa8, 0x37, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x24, 0xbc, 0xc9,
-  0xe6, 0x25, 0x6f, 0xae, 0x65, 0x4c, 0x09, 0x7e, 0xc2, 0x9e, 0xdc, 0xdc,
-  0xec, 0x77, 0x7f, 0x2d, 0x82, 0xa6, 0xff, 0x87, 0xab, 0xe8, 0x3d, 0x47,
-  0x5b, 0x68, 0x82, 0xed, 0xd2, 0x15, 0x13, 0x07, 0x2f, 0x55, 0x7d, 0xf6,
-  0x96, 0x00, 0x2f, 0x15, 0x6b, 0x55, 0x9b, 0x92, 0xeb, 0xf9, 0x86, 0x02,
-  0xf1, 0xee, 0x18, 0x2c, 0xcb, 0x38, 0x1e, 0xb7, 0xfb, 0x4a, 0x18, 0x58,
-  0xcc, 0x68, 0x35, 0xa8, 0x76, 0xb8, 0x1f, 0x23, 0x3c, 0x2a, 0x58, 0x5f,
-  0xab, 0xf9, 0xf0, 0x3e, 0xd4, 0xa5, 0xfc, 0x17, 0xf0, 0x11, 0x28, 0x7a,
-  0xcd, 0x4d, 0x38, 0x9c, 0xaf, 0xd2, 0xbf, 0x15, 0x09, 0xc0, 0x66, 0x8b,
-  0x93, 0xc2, 0x08, 0x1b, 0x2e, 0x26, 0x97, 0x52, 0x4c, 0x0e, 0x5c, 0x2a,
-  0x4a, 0xc3, 0x23, 0x03, 0xa0, 0x80, 0x7f, 0x51, 0xa0, 0xc8, 0x27, 0x86,
-  0x63, 0x07, 0xa7, 0x51, 0x53, 0x8c, 0xe0, 0x18, 0xff, 0x4a, 0x4b, 0xbb,
-  0x55, 0x71, 0x27, 0x70, 0x19, 0xfa, 0xdd, 0x3e, 0x06, 0x4d, 0xe1, 0x54,
-  0x29, 0x8c, 0x40, 0xc6, 0x68, 0x63, 0xbb, 0x06, 0xb6, 0xf6, 0x8b, 0x5b,
-  0x4c, 0x70, 0xcd, 0xd1, 0x01, 0xd2, 0x0a, 0x58, 0x7c, 0xf3, 0xc6, 0xbb,
-  0x4b, 0xcc, 0x55, 0xf6, 0xeb, 0xb2, 0xd9, 0x46, 0xd1, 0x01, 0x99, 0x9c,
-  0x2d, 0xd2, 0xb8, 0xf1, 0x6d, 0x12, 0x92, 0xf5, 0xa7, 0x44, 0x65, 0x3c,
-  0xff, 0xb9, 0xe5, 0x2e, 0xe0, 0x0f, 0x1c, 0x34, 0x0d, 0x6f, 0x2a, 0xcb,
-  0xc1, 0x51, 0xaf, 0x5f, 0xc5, 0x81, 0x5e, 0x05, 0xe2, 0xf0, 0x49, 0x7f,
-  0x6f, 0x35, 0x87, 0x17, 0x67, 0x26, 0x15, 0xf4, 0x3e, 0xe1, 0xc8, 0x7a,
-  0x13, 0xff, 0x52, 0x84, 0x8a, 0x84, 0xe8, 0x09, 0x29, 0xcd, 0x5e, 0xb0,
-  0xae, 0xe4, 0x16, 0x7d, 0x97, 0xce, 0x9d, 0xfe, 0xa7, 0x9d, 0x7a, 0x6a,
-  0x1d, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94, 0xa7, 0x4a, 0x87, 0xb5, 0xab,
-  0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x82, 0x03,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
   0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
-  0x6c, 0xb7, 0xb7, 0x7d, 0xfe, 0xe4, 0x37, 0x58, 0x0b, 0x5b, 0x5c, 0x4f,
-  0x25, 0x15, 0x57, 0x19, 0x3d, 0x4c, 0x6c, 0xc4, 0x30, 0x0d, 0x06, 0x09,
+  0x52, 0xe9, 0x66, 0x81, 0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82,
+  0x66, 0xd8, 0x3d, 0x2b, 0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42, 0x32, 0x30, 0x1e, 0x17, 0x0d,
-  0x32, 0x34, 0x30, 0x31, 0x32, 0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38,
-  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32,
-  0x30, 0x30, 0x38, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42,
-  0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x33, 0x39,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x33, 0x39, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x4b,
+  0x31, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
   0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
-  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdd, 0xda,
-  0x18, 0xf9, 0x43, 0x61, 0xe4, 0x9b, 0x1e, 0x0a, 0x6c, 0x97, 0xfc, 0x3e,
-  0x9d, 0x0f, 0x80, 0xac, 0xbc, 0x0a, 0xbe, 0x4c, 0x78, 0x7a, 0xa2, 0x41,
-  0xe5, 0x0e, 0x43, 0x41, 0xe4, 0xb5, 0x8a, 0xb2, 0x5e, 0xa2, 0x49, 0x97,
-  0xe1, 0x20, 0x33, 0xb0, 0x13, 0xb3, 0x15, 0xf5, 0x33, 0x83, 0x78, 0x53,
-  0x40, 0x14, 0xc5, 0x07, 0xa6, 0xde, 0xf9, 0x5e, 0xe9, 0xa5, 0x75, 0x97,
-  0xbb, 0xf9, 0xd4, 0xf2, 0x44, 0x8f, 0x7c, 0x98, 0x58, 0x34, 0xb4, 0x2c,
-  0x1d, 0x70, 0x28, 0xf6, 0x37, 0x63, 0x68, 0x15, 0xae, 0x09, 0x12, 0x3d,
-  0x69, 0xf6, 0x7d, 0x5e, 0x5b, 0x37, 0xa1, 0x7b, 0x4e, 0x34, 0xb2, 0x44,
-  0xe8, 0x0a, 0x0b, 0xbb, 0x61, 0xf6, 0xda, 0xcf, 0x93, 0xc9, 0x34, 0xbc,
-  0x5e, 0x05, 0x5e, 0x42, 0x8d, 0x1e, 0x8a, 0x2c, 0x33, 0x4f, 0xc6, 0x12,
-  0x92, 0x74, 0x8e, 0x0e, 0x9e, 0x3c, 0x20, 0xf9, 0x69, 0xb8, 0xf1, 0x36,
-  0xe7, 0xdb, 0x73, 0x9a, 0x59, 0x93, 0xfe, 0xb1, 0x6d, 0x3f, 0x90, 0xcd,
-  0x06, 0x2c, 0x23, 0x30, 0x89, 0x5d, 0xc0, 0xf1, 0xec, 0xc3, 0x1b, 0x13,
-  0x4a, 0xc7, 0x55, 0xbb, 0x6f, 0x58, 0x12, 0xa4, 0xaf, 0xc0, 0x6a, 0x7e,
-  0x8a, 0x8d, 0xa1, 0x1d, 0xe6, 0xf7, 0x84, 0x9c, 0xc2, 0x4a, 0x5f, 0xd3,
-  0x63, 0xeb, 0x61, 0x7d, 0x60, 0x66, 0x20, 0xe4, 0xa7, 0x98, 0x17, 0x1b,
-  0x57, 0x3b, 0xe5, 0x53, 0x22, 0x14, 0x4c, 0x0a, 0x4d, 0x4d, 0x1e, 0x71,
-  0x32, 0x11, 0x11, 0x22, 0xbe, 0x80, 0x90, 0x81, 0x9d, 0xb5, 0xdc, 0x96,
-  0x50, 0x3b, 0x6f, 0x16, 0x42, 0xab, 0x59, 0xa7, 0x8a, 0xda, 0xcb, 0x5d,
-  0x33, 0x19, 0x5d, 0x5e, 0x63, 0x8e, 0x64, 0x4e, 0x57, 0x1e, 0x11, 0xb5,
-  0x6a, 0xa9, 0x34, 0x77, 0x42, 0xa9, 0xab, 0x45, 0xd3, 0x57, 0xb2, 0x48,
-  0xb0, 0xd7, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
-  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9e, 0x35,
-  0x7c, 0xbf, 0x09, 0x7f, 0x5c, 0xb8, 0x3f, 0x5f, 0xf1, 0x2d, 0xd2, 0x45,
-  0xcc, 0x21, 0xfe, 0x4d, 0x74, 0x19, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
-  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9e, 0x35, 0x7c, 0xbf, 0x09,
-  0x7f, 0x5c, 0xb8, 0x3f, 0x5f, 0xf1, 0x2d, 0xd2, 0x45, 0xcc, 0x21, 0xfe,
-  0x4d, 0x74, 0x19, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb4, 0xbd,
+  0xd5, 0x2a, 0xdb, 0x3a, 0x4d, 0x37, 0x36, 0x4d, 0xbd, 0x2d, 0xdd, 0x31,
+  0xa0, 0x7c, 0x7b, 0x7e, 0xe9, 0x55, 0x50, 0x4b, 0xe5, 0x61, 0x69, 0x6e,
+  0x08, 0xe2, 0x82, 0x54, 0xfb, 0x00, 0xb6, 0x47, 0x01, 0x5c, 0x5b, 0x73,
+  0xa3, 0xde, 0x30, 0xa7, 0xd9, 0x8c, 0xeb, 0x4f, 0xda, 0x0a, 0x94, 0xc1,
+  0xd3, 0x97, 0x5c, 0xa7, 0x6f, 0x9e, 0xaa, 0xec, 0xa4, 0xf6, 0x8e, 0x73,
+  0x60, 0xe3, 0xac, 0xf7, 0x7e, 0x9b, 0x08, 0x30, 0x52, 0xff, 0x95, 0xb3,
+  0x7f, 0xf6, 0x6d, 0x5f, 0xa3, 0xcd, 0xa6, 0x56, 0x71, 0x33, 0xd0, 0xb4,
+  0xff, 0x03, 0x8c, 0xb2, 0x32, 0x91, 0x48, 0x85, 0x24, 0xd0, 0x68, 0x4c,
+  0xce, 0x62, 0xea, 0xca, 0xad, 0xa7, 0x72, 0x35, 0x14, 0xc3, 0x1d, 0x0a,
+  0x36, 0xb0, 0xd4, 0xcb, 0xd8, 0x0c, 0x98, 0xb9, 0x5f, 0x9b, 0xaa, 0x68,
+  0x27, 0xfc, 0xe2, 0xa0, 0x36, 0xee, 0xbc, 0x64, 0xfe, 0x8c, 0x50, 0xff,
+  0xb1, 0x4b, 0x68, 0xcb, 0x94, 0x38, 0x30, 0x9d, 0x67, 0x62, 0x55, 0x1e,
+  0x63, 0x79, 0x1b, 0xad, 0xd2, 0x5e, 0xb6, 0x5f, 0xb2, 0xc5, 0x0d, 0x9d,
+  0x4d, 0xc8, 0xa4, 0xfc, 0x83, 0x5e, 0x18, 0xee, 0xd1, 0xd7, 0x76, 0xe4,
+  0xb0, 0x2b, 0xd0, 0x2c, 0x17, 0xc9, 0x90, 0xe8, 0x80, 0x55, 0x57, 0xbb,
+  0x0a, 0x46, 0x21, 0x7e, 0x3b, 0x14, 0x77, 0xf0, 0xd8, 0x0c, 0x16, 0x37,
+  0x83, 0x8e, 0x1f, 0x4f, 0xaa, 0x00, 0x5c, 0x5d, 0x47, 0xd4, 0xcf, 0x73,
+  0x86, 0x3c, 0x58, 0x87, 0x82, 0xb1, 0x1d, 0x23, 0xac, 0x24, 0x76, 0xc8,
+  0xcb, 0xca, 0x4f, 0xd6, 0xf0, 0x8f, 0xcd, 0xa9, 0x63, 0xce, 0x57, 0x71,
+  0x88, 0xba, 0x20, 0x04, 0x94, 0x83, 0x87, 0x97, 0xc7, 0xd1, 0xdf, 0xc1,
+  0x1c, 0x07, 0x3f, 0x08, 0x53, 0x11, 0x9a, 0x07, 0x9f, 0xd9, 0x37, 0x96,
+  0x57, 0x55, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x09, 0x75,
+  0x54, 0x4c, 0x71, 0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87,
+  0xe2, 0x96, 0xcb, 0x57, 0x99, 0xc4, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x09, 0x75, 0x54, 0x4c, 0x71,
+  0xbc, 0xf2, 0x1e, 0x6b, 0x39, 0x31, 0xfe, 0xb7, 0x87, 0xe2, 0x96, 0xcb,
+  0x57, 0x99, 0xc4, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
   0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
   0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
-  0x82, 0x01, 0x01, 0x00, 0x23, 0x06, 0x8e, 0x17, 0x9f, 0xe8, 0x61, 0x2e,
-  0x40, 0xc0, 0x60, 0xa3, 0x8c, 0x7b, 0xf8, 0x3a, 0x45, 0x45, 0xe4, 0xdd,
-  0x30, 0x0a, 0x6b, 0x3d, 0x4c, 0x57, 0xd8, 0x89, 0x65, 0x16, 0x47, 0xe2,
-  0xb1, 0x82, 0xdf, 0x02, 0x18, 0x0b, 0xb4, 0xba, 0xea, 0xe9, 0xde, 0xb5,
-  0xb8, 0x7c, 0x70, 0xb1, 0xf0, 0x59, 0xc2, 0xeb, 0x57, 0xa6, 0x09, 0x2d,
-  0x0e, 0x83, 0xe0, 0x4e, 0x5a, 0xa1, 0x84, 0x2c, 0x46, 0x05, 0x38, 0x5c,
-  0x7f, 0xab, 0xc5, 0xc8, 0x34, 0x39, 0xbb, 0xf1, 0x2c, 0xa2, 0x07, 0x14,
-  0x8f, 0x35, 0x8e, 0x79, 0xb6, 0x5a, 0x02, 0x24, 0x53, 0xe3, 0xc7, 0x59,
-  0x3a, 0x79, 0x0c, 0x43, 0xd4, 0xb8, 0x5c, 0x38, 0x91, 0x00, 0x42, 0xc9,
-  0x64, 0x8e, 0x6e, 0x81, 0x12, 0x0f, 0x2b, 0xce, 0x4d, 0x19, 0x7f, 0xa7,
-  0x8d, 0xc8, 0x7f, 0x80, 0xd1, 0xa9, 0xb7, 0x4a, 0xdf, 0x1a, 0x42, 0xc7,
-  0x7e, 0x96, 0x12, 0x31, 0x6f, 0xdc, 0x11, 0x1a, 0x4e, 0x2b, 0xbd, 0x4f,
-  0xbd, 0x4f, 0x17, 0x0d, 0x7e, 0x26, 0x46, 0xf4, 0xc5, 0x1a, 0x55, 0x6a,
-  0x1b, 0x00, 0x5f, 0xa3, 0x9f, 0xec, 0x97, 0x32, 0xc0, 0x49, 0x5b, 0xe8,
-  0xd8, 0x66, 0x11, 0x61, 0x16, 0x7d, 0x7a, 0x39, 0x24, 0x4b, 0x07, 0xc8,
-  0x33, 0xb3, 0x54, 0xcf, 0xfd, 0x7b, 0xb9, 0x61, 0xac, 0x6e, 0x5b, 0xa0,
-  0x7c, 0x20, 0x1a, 0x3b, 0xfa, 0x01, 0x24, 0x52, 0x75, 0x40, 0x17, 0x49,
-  0xc5, 0xbc, 0x27, 0x2e, 0xf4, 0x83, 0x54, 0x16, 0xdc, 0x73, 0x14, 0x3e,
-  0x49, 0x79, 0xe3, 0xea, 0xd7, 0x98, 0xe4, 0xc3, 0xb8, 0x46, 0x82, 0x22,
-  0xe6, 0xe9, 0xb9, 0x5d, 0x0e, 0xa5, 0xe8, 0x66, 0x1b, 0x31, 0x7c, 0x83,
-  0xd8, 0x70, 0x95, 0x51, 0x99, 0xe9, 0x38, 0x77, 0x19, 0xef, 0xbe, 0xfd,
-  0xcb, 0x5a, 0x9e, 0xcd, 0x0e, 0x7f, 0x92, 0x3b
+  0x82, 0x01, 0x01, 0x00, 0x18, 0x8f, 0x0f, 0xbb, 0x2b, 0x58, 0xe1, 0x96,
+  0x9c, 0xd2, 0x9d, 0x38, 0x1e, 0x10, 0x1f, 0x98, 0x21, 0xb3, 0x13, 0x49,
+  0x47, 0x09, 0xd5, 0x4c, 0x97, 0x8f, 0xbb, 0x18, 0xd7, 0xe2, 0x8c, 0x0d,
+  0x67, 0x23, 0xf3, 0x3b, 0xfc, 0x7f, 0x7a, 0x42, 0xb5, 0x7d, 0xb4, 0x32,
+  0x10, 0xd4, 0xae, 0x42, 0x7f, 0xb8, 0x61, 0xbe, 0x82, 0x84, 0x7e, 0xa2,
+  0xed, 0xca, 0xd0, 0x0e, 0x1e, 0xa7, 0x6f, 0x74, 0xb3, 0xe7, 0xbe, 0x8e,
+  0xbd, 0x8d, 0x55, 0xcd, 0x4a, 0x3f, 0x2b, 0x14, 0x7c, 0xe4, 0x12, 0xf6,
+  0xb5, 0xcf, 0x80, 0xa5, 0xbc, 0x06, 0x27, 0xcd, 0xa1, 0x99, 0x90, 0x06,
+  0x16, 0x8f, 0x66, 0xe4, 0x2e, 0xb2, 0x5a, 0x00, 0xaf, 0xe5, 0x72, 0x4a,
+  0x7a, 0x7d, 0x81, 0xa5, 0x85, 0xe1, 0x65, 0x9f, 0xa0, 0xf8, 0x96, 0xda,
+  0x92, 0xbf, 0xa3, 0xce, 0xc6, 0xfc, 0x98, 0x0c, 0xe8, 0x54, 0x1a, 0x38,
+  0xd7, 0x6e, 0x95, 0x7d, 0x04, 0xe9, 0xc3, 0x26, 0x89, 0xfb, 0x3a, 0xe0,
+  0x2e, 0xae, 0x6a, 0xfe, 0xec, 0x6f, 0xe2, 0x6a, 0xcf, 0x6e, 0x67, 0x52,
+  0x3b, 0xb7, 0x11, 0xb4, 0x68, 0x77, 0xb5, 0x99, 0xe5, 0x01, 0x68, 0xbb,
+  0x94, 0xe2, 0x00, 0x12, 0x86, 0x92, 0x27, 0xa0, 0x8b, 0xbe, 0x1d, 0x62,
+  0xce, 0x7a, 0x1e, 0x6a, 0xa7, 0xfe, 0x28, 0x20, 0xfc, 0xd6, 0x99, 0xf5,
+  0xde, 0xd4, 0xd1, 0xc3, 0xfb, 0x3a, 0x04, 0x66, 0xa4, 0x1e, 0x77, 0x22,
+  0x0a, 0xa8, 0x53, 0xbd, 0x3d, 0x6a, 0x97, 0x88, 0x4e, 0x1f, 0x2e, 0xdd,
+  0x93, 0x08, 0x70, 0x80, 0xdc, 0x1a, 0xe2, 0x50, 0xb7, 0x04, 0x70, 0xa2,
+  0x3b, 0xaf, 0x7c, 0x4e, 0x5f, 0xf9, 0xa9, 0x40, 0x96, 0xce, 0xe4, 0xc4,
+  0x82, 0x69, 0x69, 0xc5, 0x24, 0xa8, 0xd8, 0x4c, 0xc1, 0x67, 0xa2, 0xfb,
+  0x09, 0x11, 0xb8, 0x81, 0xac, 0xd9, 0x67, 0x84, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x50, 0x4b, 0x31, 0x02, 0x14, 0x52, 0xe9, 0x66, 0x81,
+  0x55, 0x20, 0x73, 0xd5, 0x35, 0x3f, 0xbd, 0x82, 0x66, 0xd8, 0x3d, 0x2b,
+  0x1a, 0x70, 0x67, 0x79, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x1e, 0xe9, 0x31, 0x36, 0xcc, 0x55, 0xed, 0x16, 0xaa, 0xa5,
+  0xe0, 0x4b, 0x92, 0x8f, 0xae, 0xfe, 0xfd, 0xa2, 0x39, 0x0e, 0x33, 0xbe,
+  0x44, 0x97, 0xf4, 0x45, 0x31, 0xfe, 0xde, 0x9a, 0x29, 0x07, 0x52, 0xc2,
+  0x25, 0x1d, 0xe5, 0xf0, 0xc4, 0xf0, 0x04, 0x09, 0x9c, 0x62, 0x63, 0x3f,
+  0x36, 0xcb, 0xca, 0x08, 0xdb, 0xbc, 0xe8, 0x65, 0x57, 0xe3, 0x10, 0xb1,
+  0xb0, 0x4b, 0xf6, 0x1b, 0xf8, 0x1d, 0x9f, 0xd5, 0x2f, 0xe7, 0xf1, 0x98,
+  0xe2, 0x3f, 0x24, 0xd4, 0xba, 0xb8, 0x27, 0xca, 0x53, 0xb3, 0xf8, 0x07,
+  0x45, 0x8e, 0xeb, 0x31, 0x0d, 0x32, 0x0b, 0xd2, 0xf0, 0xcf, 0x65, 0x78,
+  0x8b, 0xcf, 0x21, 0x5f, 0x8b, 0x8a, 0x18, 0x53, 0x74, 0x92, 0x9d, 0x17,
+  0x56, 0x92, 0xf2, 0xbe, 0x28, 0xfe, 0xbc, 0x51, 0xcf, 0xd1, 0x68, 0x77,
+  0xee, 0x8d, 0xb6, 0xe6, 0x41, 0x44, 0x01, 0x38, 0x7b, 0x4e, 0x1e, 0x32,
+  0xc3, 0x68, 0x1d, 0xfa, 0xd0, 0xd7, 0x6c, 0x7a, 0x00, 0x2f, 0x82, 0x6d,
+  0x95, 0x36, 0x2d, 0x6f, 0x3d, 0x71, 0xd8, 0xf3, 0x77, 0xc6, 0xb1, 0xfb,
+  0x85, 0x84, 0x3d, 0x72, 0xae, 0x97, 0x1a, 0x5c, 0x3a, 0x4d, 0xdc, 0xcd,
+  0x39, 0xd9, 0xe2, 0xda, 0x40, 0x68, 0x31, 0xcd, 0x53, 0x33, 0xc1, 0xeb,
+  0x1b, 0x16, 0x8e, 0x65, 0x6c, 0xec, 0xbb, 0x7a, 0xf3, 0xd6, 0xb1, 0xc3,
+  0x88, 0x8e, 0x36, 0x3e, 0x1b, 0x9f, 0xc0, 0x16, 0x75, 0x35, 0x3a, 0xc6,
+  0x07, 0x1c, 0x2f, 0x68, 0x2e, 0xf7, 0x31, 0x56, 0xb3, 0x6b, 0xcc, 0x50,
+  0xdc, 0x7c, 0x29, 0x67, 0xd7, 0x25, 0xa7, 0xa3, 0xd3, 0xe6, 0xe8, 0x2b,
+  0x19, 0x63, 0xb9, 0x32, 0x26, 0xba, 0x32, 0x13, 0x5c, 0x85, 0x94, 0x18,
+  0x2f, 0x03, 0xe4, 0x4b, 0xe4, 0x04, 0xb9, 0x3c, 0xad, 0xce, 0x63, 0x9e,
+  0xf1, 0xb7, 0x69, 0xce, 0x08, 0xa3, 0xa1, 0x59, 0xc0, 0xa5, 0xe4, 0x94,
+  0xa7, 0x4a, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72, 0x37, 0x03,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03,
+  0x02, 0x01, 0x02, 0x02, 0x14, 0x6d, 0x3f, 0xf2, 0x17, 0xc7, 0x96, 0x91,
+  0xa8, 0x46, 0x77, 0x42, 0x38, 0x7f, 0xc7, 0xb8, 0xf8, 0x5d, 0x50, 0xcc,
+  0x47, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42,
+  0x32, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31,
+  0x30, 0x32, 0x31, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36,
+  0x30, 0x39, 0x31, 0x30, 0x32, 0x31, 0x34, 0x39, 0x5a, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x44, 0x42, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
+  0x01, 0x01, 0x00, 0xb9, 0x73, 0xdf, 0x1a, 0xca, 0x81, 0xea, 0x60, 0xcc,
+  0x3b, 0x2f, 0xc8, 0x51, 0xd9, 0x46, 0xde, 0x99, 0x1e, 0xed, 0x29, 0x38,
+  0xff, 0x79, 0x9f, 0x1a, 0x85, 0x91, 0x27, 0x88, 0x32, 0x76, 0xa8, 0xe9,
+  0x61, 0x9e, 0xe2, 0x09, 0xee, 0x5d, 0x08, 0x9e, 0x0a, 0x4b, 0x0a, 0x78,
+  0x7d, 0x28, 0x7f, 0x0c, 0x64, 0x7b, 0x57, 0xe3, 0xf5, 0x74, 0xf3, 0xe3,
+  0xa5, 0x9f, 0x4f, 0xd8, 0x69, 0xc7, 0x91, 0xcc, 0xb1, 0xb8, 0x20, 0xe0,
+  0x12, 0x64, 0xc2, 0xfc, 0xdf, 0x3d, 0x32, 0x96, 0xed, 0xf5, 0x64, 0x69,
+  0x22, 0xf8, 0x9e, 0x09, 0x8e, 0x82, 0xe4, 0xe5, 0x17, 0x0a, 0x1c, 0x17,
+  0x87, 0x7c, 0x3b, 0xd3, 0x79, 0xb1, 0x0b, 0x6a, 0xda, 0xa5, 0x4e, 0xd2,
+  0x84, 0x12, 0x2e, 0x04, 0x4c, 0xde, 0xbf, 0xa5, 0x3d, 0x29, 0xb7, 0x2f,
+  0x84, 0xf6, 0x61, 0x1e, 0x37, 0x51, 0x0f, 0xea, 0xdf, 0xd3, 0xb1, 0xb4,
+  0xb9, 0x39, 0xb7, 0xb7, 0x03, 0xdb, 0xd5, 0x6d, 0xd6, 0x67, 0x85, 0xeb,
+  0xd2, 0x5e, 0x68, 0x22, 0x5d, 0xa0, 0x8d, 0x83, 0x50, 0x18, 0x8e, 0xa1,
+  0xaf, 0x18, 0x09, 0xc5, 0x0b, 0x5c, 0xa9, 0x61, 0x2b, 0x79, 0x14, 0xde,
+  0xa1, 0xf3, 0x8f, 0xdf, 0x8d, 0x7a, 0xa1, 0xe7, 0x4d, 0xeb, 0x4f, 0xa7,
+  0xd4, 0x47, 0x5e, 0x7e, 0xc8, 0x27, 0xd0, 0xfe, 0xff, 0x13, 0xf5, 0x6a,
+  0x6f, 0x3f, 0x28, 0x73, 0x7c, 0x76, 0x63, 0xc8, 0xb3, 0x22, 0x40, 0x24,
+  0xe1, 0xe5, 0xcd, 0x61, 0x35, 0x68, 0x70, 0x51, 0x9d, 0x22, 0x33, 0x7e,
+  0xd0, 0xee, 0xb6, 0xdc, 0x63, 0xf2, 0xe4, 0x3b, 0xbf, 0xdc, 0x4a, 0x48,
+  0x0b, 0x17, 0x1f, 0x78, 0xbd, 0x08, 0x4d, 0x65, 0xd1, 0x0a, 0x67, 0x48,
+  0xc3, 0x69, 0x32, 0x07, 0x2b, 0x40, 0xf0, 0x78, 0xd7, 0x85, 0x9f, 0x47,
+  0x56, 0xa4, 0xd7, 0x2f, 0x42, 0x47, 0xc5, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x11, 0xe9, 0x37, 0x6b, 0xaa, 0x3e, 0x5c, 0x38, 0x16,
+  0x40, 0x4f, 0x4b, 0x08, 0x64, 0x17, 0x0d, 0x47, 0xd4, 0x8b, 0xa1, 0x30,
+  0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
+  0x11, 0xe9, 0x37, 0x6b, 0xaa, 0x3e, 0x5c, 0x38, 0x16, 0x40, 0x4f, 0x4b,
+  0x08, 0x64, 0x17, 0x0d, 0x47, 0xd4, 0x8b, 0xa1, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01,
+  0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
+  0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x17, 0xf9, 0x7f,
+  0x9f, 0x37, 0xfb, 0x0b, 0x79, 0x3b, 0x79, 0x7b, 0x9d, 0x50, 0xa8, 0x01,
+  0x21, 0xdb, 0x41, 0xa9, 0xe0, 0x5c, 0x45, 0xe6, 0x9e, 0x58, 0xe0, 0xa8,
+  0x5a, 0x00, 0x0a, 0xb3, 0x22, 0x78, 0x0f, 0x81, 0x13, 0x9b, 0x39, 0x1b,
+  0x2e, 0xb4, 0xc6, 0x3c, 0x1a, 0x72, 0xf9, 0x8f, 0xcb, 0x89, 0xe1, 0x20,
+  0xe8, 0xdf, 0x31, 0x4c, 0x45, 0x94, 0x23, 0x2f, 0x06, 0x63, 0x08, 0x67,
+  0x53, 0xd6, 0x66, 0x60, 0x39, 0x09, 0x45, 0x6d, 0x2a, 0xa6, 0x58, 0xe5,
+  0x0e, 0xd3, 0x34, 0xa1, 0x34, 0x49, 0xf4, 0xd9, 0xb5, 0x37, 0x34, 0xd0,
+  0xec, 0x44, 0xe3, 0x5d, 0x21, 0x47, 0xac, 0xb8, 0x1e, 0xed, 0x26, 0xf2,
+  0x39, 0xb1, 0xb9, 0xae, 0xe2, 0x51, 0x89, 0x92, 0x52, 0x48, 0x4c, 0xb3,
+  0x00, 0x41, 0xdd, 0x67, 0xfb, 0x98, 0x42, 0x46, 0x59, 0x87, 0x27, 0xcb,
+  0x0f, 0x9e, 0x96, 0x6d, 0xac, 0x69, 0xd7, 0x9e, 0xcc, 0x54, 0x40, 0x14,
+  0xe0, 0x4a, 0x6b, 0x56, 0x06, 0xd1, 0x9f, 0x09, 0xad, 0x60, 0x66, 0x40,
+  0xd8, 0x41, 0x21, 0x42, 0x12, 0xa4, 0x32, 0xfa, 0xe2, 0x87, 0x9a, 0x54,
+  0x23, 0x85, 0x7e, 0x11, 0xf8, 0x71, 0x7e, 0x1f, 0x84, 0x4a, 0xa0, 0x70,
+  0x7c, 0xc4, 0xb6, 0x6a, 0xd3, 0xc5, 0xcf, 0x70, 0xb8, 0x76, 0x74, 0x1a,
+  0x0f, 0x24, 0xc4, 0x4a, 0x20, 0x75, 0x58, 0x23, 0x08, 0xd4, 0x4f, 0x5b,
+  0xda, 0xaa, 0x9f, 0x21, 0xd1, 0x8c, 0x08, 0x69, 0x31, 0x9b, 0x89, 0x18,
+  0xf7, 0xbe, 0xf0, 0xdd, 0x76, 0x85, 0x46, 0xff, 0xe6, 0x4d, 0xe6, 0xb7,
+  0xe4, 0xfb, 0xc7, 0x64, 0xc5, 0x43, 0x47, 0x8d, 0xf6, 0xbc, 0x4b, 0x5e,
+  0x24, 0x4d, 0xe6, 0x57, 0x31, 0x6e, 0x82, 0x02, 0x7e, 0xbd, 0x73, 0xb9,
+  0xc6, 0x14, 0x99, 0x99, 0x8c, 0xed, 0x1b, 0xa6, 0xaf, 0x59, 0x83, 0x1b,
+  0xa4
 };
-unsigned int DB2_auth_len = 2048;
+unsigned int DB2_auth_len = 2029;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/var.h b/components/service/uefi/smm_variable/test/service/auth_vectors/var.h
index e2ae64a..6ceb372 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/var.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/var.h
@@ -7,277 +7,153 @@
  */
 
 unsigned char VAR_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x16, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x2d, 0x56, 0x6b, 0xbb, 0xa5,
-  0x07, 0xa3, 0xa2, 0x44, 0x17, 0xca, 0x1c, 0xe2, 0xfc, 0xd3, 0x2e, 0x3c,
-  0x6b, 0x4b, 0x65, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x44, 0x42, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x44, 0x88, 0xdb, 0x5e, 0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe,
+  0x7d, 0x2c, 0xa2, 0xf6, 0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42, 0x31, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xac, 0x13, 0xa9, 0xbb, 0x26, 0x22, 0x4c,
-  0x0f, 0xa9, 0x0a, 0x55, 0xbb, 0x40, 0x66, 0x73, 0xb2, 0x9f, 0x0e, 0x3a,
-  0xe8, 0x08, 0xce, 0xcd, 0x0d, 0x2b, 0xd9, 0xd1, 0x7e, 0x0b, 0x37, 0x6a,
-  0xf7, 0x7b, 0xb0, 0x21, 0x24, 0x61, 0x1d, 0xbb, 0x34, 0xb6, 0x28, 0x7b,
-  0xae, 0x77, 0x5b, 0x78, 0xab, 0x27, 0x5d, 0x65, 0xea, 0xe2, 0x8b, 0x89,
-  0x05, 0x2c, 0x61, 0xe6, 0x4d, 0x7b, 0x9f, 0xbc, 0xaa, 0x21, 0xff, 0x50,
-  0x86, 0x17, 0x7d, 0x41, 0x48, 0x80, 0xea, 0x60, 0x2c, 0xe9, 0x66, 0x20,
-  0x78, 0x84, 0xb6, 0x20, 0x1b, 0x47, 0xbd, 0x71, 0x26, 0x77, 0x4d, 0x41,
-  0x97, 0x65, 0x6b, 0x08, 0xcb, 0x68, 0xb5, 0xab, 0x73, 0x4a, 0xb8, 0x11,
-  0x60, 0x16, 0x3b, 0xc7, 0x34, 0x22, 0x01, 0xf7, 0x65, 0xbf, 0xf5, 0x8e,
-  0x3b, 0x93, 0xc4, 0x9f, 0xf5, 0xe8, 0xc2, 0x1f, 0xf9, 0x9d, 0xce, 0xf5,
-  0xa1, 0xe6, 0x60, 0x3c, 0xa6, 0xa7, 0xb6, 0xe3, 0xea, 0xc1, 0x18, 0x92,
-  0xde, 0x01, 0xe5, 0xbd, 0xf9, 0x9a, 0x8c, 0x39, 0x54, 0x67, 0x73, 0x57,
-  0xaa, 0x26, 0xce, 0x6f, 0x01, 0x7c, 0x29, 0xc1, 0xba, 0xf6, 0xad, 0x5f,
-  0x55, 0x12, 0x54, 0x65, 0xcd, 0xe6, 0xe5, 0x13, 0x4f, 0xf3, 0xc1, 0xed,
-  0xba, 0x1f, 0x32, 0x1a, 0x41, 0x02, 0xfe, 0x2b, 0x41, 0x07, 0xce, 0xc1,
-  0x69, 0x91, 0x93, 0xc8, 0x3d, 0x6d, 0x7c, 0xa8, 0xc8, 0xcb, 0xaa, 0x39,
-  0xf6, 0x59, 0x6f, 0x40, 0x48, 0xef, 0x16, 0xf7, 0xf3, 0xdf, 0xd5, 0xc2,
-  0x1a, 0xa6, 0xed, 0xff, 0x05, 0xa5, 0xac, 0x39, 0x32, 0x18, 0xcb, 0xe1,
-  0x87, 0x0f, 0xf8, 0x04, 0x55, 0x50, 0xb7, 0xfb, 0xa2, 0xa2, 0x05, 0x33,
-  0xa5, 0x15, 0x46, 0xd8, 0x14, 0x35, 0xd2, 0x08, 0x14, 0x48, 0x15, 0x45,
-  0x0a, 0x7d, 0xfd, 0xa5, 0x36, 0x7e, 0xd4, 0x23, 0xb9, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x28, 0x8e, 0x10, 0x73, 0x79, 0x18, 0xac,
-  0xe1, 0xfc, 0xd1, 0x85, 0x96, 0x35, 0x62, 0xc3, 0x6c, 0xff, 0x30, 0x20,
-  0xcc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x28, 0x8e, 0x10, 0x73, 0x79, 0x18, 0xac, 0xe1, 0xfc, 0xd1,
-  0x85, 0x96, 0x35, 0x62, 0xc3, 0x6c, 0xff, 0x30, 0x20, 0xcc, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a,
-  0x19, 0x4b, 0x7a, 0xe2, 0x4c, 0xbb, 0x7a, 0xde, 0x38, 0xc0, 0xd2, 0x45,
-  0x8a, 0x18, 0x9e, 0x80, 0xfa, 0xfb, 0xed, 0x97, 0x0d, 0x29, 0x7a, 0xf3,
-  0x52, 0xc4, 0xc5, 0xfa, 0x57, 0x0b, 0x63, 0xf5, 0x7b, 0x45, 0x11, 0x7c,
-  0xed, 0x3e, 0xa1, 0x40, 0xd3, 0xef, 0x51, 0xb8, 0x18, 0x31, 0xba, 0xa4,
-  0x7f, 0x1f, 0x95, 0x3b, 0xd4, 0xae, 0x89, 0x47, 0xf2, 0x40, 0xa3, 0x04,
-  0x20, 0x31, 0x55, 0xb7, 0xf7, 0xcd, 0x05, 0x2b, 0x2c, 0xca, 0x55, 0xa6,
-  0xed, 0x0e, 0x84, 0x43, 0xfb, 0xcd, 0x22, 0xeb, 0xb9, 0x1e, 0xd4, 0x36,
-  0x49, 0x14, 0xcf, 0xa6, 0x75, 0x53, 0x1a, 0x9b, 0x64, 0x05, 0x18, 0x23,
-  0xa4, 0x4e, 0xb1, 0x95, 0x24, 0x07, 0xce, 0xca, 0x79, 0x57, 0x3a, 0x7f,
-  0xd6, 0x02, 0x3e, 0xf7, 0x7a, 0xde, 0x68, 0xd1, 0x5c, 0xc0, 0xbd, 0x60,
-  0xed, 0x56, 0xf5, 0x9f, 0xa1, 0x94, 0x68, 0x39, 0xa6, 0x9b, 0x9d, 0xdf,
-  0x98, 0x4a, 0x34, 0x39, 0xcc, 0xd5, 0x38, 0xc8, 0x2e, 0x66, 0x69, 0xaf,
-  0x6d, 0x46, 0xc8, 0x52, 0xc4, 0x9e, 0x9f, 0xe6, 0x4f, 0xa9, 0xd2, 0xf5,
-  0x15, 0x9a, 0xa1, 0xaa, 0xab, 0x09, 0x67, 0x76, 0x62, 0x6c, 0x5c, 0xf8,
-  0x1b, 0x4c, 0x57, 0x77, 0x53, 0x2c, 0xe0, 0x91, 0x8b, 0x63, 0xd3, 0xd0,
-  0xd4, 0xad, 0x89, 0x6c, 0x3d, 0xe2, 0x9a, 0xe2, 0x75, 0xf5, 0x33, 0xd3,
-  0x74, 0x1e, 0xd6, 0xd0, 0x5c, 0x41, 0x3e, 0xa2, 0x14, 0x04, 0x90, 0xde,
-  0xfd, 0x68, 0x5d, 0xbd, 0x87, 0x4f, 0x6c, 0x00, 0xae, 0x94, 0xa4, 0xf0,
-  0x8b, 0xb4, 0x29, 0x58, 0xd8, 0xd0, 0x9c, 0xa6, 0xd3, 0x62, 0x47, 0xee,
-  0x8c, 0xf6, 0xeb, 0xe9, 0x99, 0x86, 0x45, 0x55, 0xd7, 0x91, 0xc9, 0xe6,
-  0xcb, 0x2e, 0xa2, 0x63, 0x16, 0xc9, 0x30, 0xdf, 0x72, 0x59, 0x06, 0xe8,
-  0x22, 0x6b, 0xda, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42,
-  0x31, 0x02, 0x14, 0x2d, 0x56, 0x6b, 0xbb, 0xa5, 0x07, 0xa3, 0xa2, 0x44,
-  0x17, 0xca, 0x1c, 0xe2, 0xfc, 0xd3, 0x2e, 0x3c, 0x6b, 0x4b, 0x65, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x08, 0xd6, 0x61,
-  0x1c, 0xfb, 0x7a, 0x2b, 0xfb, 0xac, 0x1e, 0x16, 0xb2, 0xa5, 0xde, 0x17,
-  0xc0, 0xb5, 0x96, 0x36, 0xff, 0x7d, 0xd8, 0x1e, 0x87, 0xfa, 0x74, 0xbc,
-  0xbb, 0xef, 0x01, 0x54, 0xd4, 0x1c, 0x85, 0xc5, 0xc7, 0x65, 0x08, 0xc3,
-  0x43, 0x27, 0xbe, 0x8e, 0x7b, 0x18, 0xfc, 0x46, 0x60, 0x81, 0xb0, 0x34,
-  0x59, 0x52, 0x76, 0x30, 0xf9, 0x64, 0x56, 0xc2, 0x80, 0x2d, 0xad, 0xf6,
-  0x2a, 0x8e, 0x5b, 0x77, 0xf3, 0xe4, 0x14, 0xef, 0xd3, 0x7f, 0x70, 0xd8,
-  0x61, 0x82, 0xcc, 0x6a, 0xa9, 0xee, 0x7c, 0x2d, 0x02, 0xd5, 0x47, 0x3c,
-  0xd7, 0xf4, 0xe5, 0xf8, 0xfc, 0xfc, 0x62, 0xea, 0x55, 0x56, 0x85, 0x92,
-  0x22, 0x28, 0x64, 0x05, 0x85, 0xd2, 0x02, 0xba, 0xcd, 0x72, 0xb3, 0x76,
-  0xfd, 0x0b, 0xcd, 0xe0, 0xa4, 0xd5, 0xa6, 0x52, 0x62, 0x74, 0x18, 0x7d,
-  0x3c, 0xa6, 0x8e, 0x7b, 0x3a, 0x5f, 0xaa, 0x78, 0x30, 0x89, 0x5d, 0xe5,
-  0x35, 0x33, 0x39, 0x62, 0x79, 0x47, 0x63, 0x33, 0x1e, 0xbd, 0xab, 0xc0,
-  0xbf, 0x4f, 0x32, 0xf3, 0x07, 0x51, 0x6b, 0xc1, 0xde, 0xbe, 0xa9, 0xf8,
-  0xa9, 0xaa, 0xd1, 0x0e, 0xc4, 0x00, 0x09, 0x08, 0xb6, 0x92, 0x2e, 0x25,
-  0x12, 0xcf, 0x76, 0x44, 0x8e, 0xf4, 0x56, 0xf1, 0xee, 0xce, 0x40, 0x51,
-  0x5d, 0xef, 0xbe, 0x40, 0xa1, 0x6a, 0x75, 0xbd, 0x2b, 0x3e, 0x80, 0x90,
-  0x71, 0xa9, 0x13, 0x68, 0xef, 0x48, 0xfb, 0x41, 0xb9, 0x9f, 0x8c, 0x93,
-  0xa6, 0xc6, 0xc1, 0x96, 0x62, 0x05, 0x1d, 0x61, 0x5a, 0xb4, 0x6c, 0x36,
-  0xd8, 0x5f, 0x57, 0x03, 0xdd, 0xa0, 0xad, 0x00, 0x39, 0x1d, 0xe6, 0x3c,
-  0xa0, 0x27, 0x98, 0xaa, 0x41, 0x34, 0x58, 0x04, 0x5c, 0x8a, 0xff, 0x46,
-  0x00, 0x42, 0xe7, 0x3f, 0x10, 0x77, 0xc6, 0x1e, 0x21, 0x0a, 0xd5, 0xe8,
-  0x57, 0x54, 0x68, 0x65, 0x20, 0x74, 0x65, 0x72, 0x6d, 0x20, 0x27, 0x74,
-  0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69,
-  0x63, 0x65, 0x27, 0x20, 0x69, 0x73, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20,
-  0x61, 0x73, 0x20, 0x61, 0x20, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c,
-  0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x20,
-  0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x70, 0x70,
-  0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x61,
-  0x74, 0x20, 0x72, 0x75, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6e,
-  0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x0a, 0x70, 0x72,
-  0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76,
-  0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x4f, 0x74,
-  0x68, 0x65, 0x72, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-  0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x79, 0x20, 0x6f, 0x6e,
-  0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65, 0x72,
-  0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x65, 0x72,
-  0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
-  0x79, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x6f, 0x70,
-  0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x69, 0x6e, 0x0a,
-  0x61, 0x20, 0x77, 0x61, 0x79, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x61,
-  0x76, 0x6f, 0x69, 0x64, 0x73, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x69,
-  0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x20, 0x64, 0x61,
-  0x74, 0x61, 0x20, 0x62, 0x65, 0x79, 0x6f, 0x6e, 0x64, 0x20, 0x74, 0x68,
-  0x65, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-  0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x20, 0x6f, 0x66, 0x20,
-  0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
-  0x65, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x77, 0x6f, 0x72,
-  0x64, 0x20, 0x27, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x27, 0x0a,
-  0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x69, 0x6d, 0x70,
-  0x6c, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20,
-  0x69, 0x6e, 0x68, 0x65, 0x72, 0x65, 0x6e, 0x74, 0x6c, 0x79, 0x20, 0x74,
-  0x72, 0x75, 0x73, 0x74, 0x77, 0x6f, 0x72, 0x74, 0x68, 0x79, 0x20, 0x61,
-  0x62, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69,
-  0x63, 0x65, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
-  0x6f, 0x6e, 0x20, 0x62, 0x75, 0x74, 0x20, 0x72, 0x61, 0x74, 0x68, 0x65,
-  0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x74, 0x68, 0x65, 0x72,
-  0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-  0x73, 0x0a, 0x70, 0x75, 0x74, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20,
-  0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69,
-  0x63, 0x65, 0x2e, 0x20, 0x4d, 0x65, 0x65, 0x74, 0x69, 0x6e, 0x67, 0x20,
-  0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20,
-  0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
-  0x72, 0x65, 0x6c, 0x69, 0x65, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x61, 0x20,
-  0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x68, 0x61, 0x72,
-  0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x66, 0x69,
-  0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x0a, 0x69, 0x6d, 0x70, 0x6c, 0x65,
-  0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72,
-  0x69, 0x74, 0x79, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73,
-  0x2e, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x41, 0x72, 0x6d, 0x20, 0x41,
-  0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x70,
-  0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x41, 0x2d, 0x70, 0x72,
-  0x6f, 0x66, 0x69, 0x6c, 0x65, 0x29, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69,
-  0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20,
-  0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
-  0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72,
-  0x64, 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2c, 0x20,
-  0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20, 0x61, 0x20, 0x72,
-  0x61, 0x6e, 0x67, 0x65, 0x0a, 0x6f, 0x66, 0x20, 0x69, 0x73, 0x6f, 0x6c,
-  0x61, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
-  0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
-  0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x66,
-  0x66, 0x65, 0x72, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65,
-  0x2d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x74,
-  0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e,
-  0x73, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x63,
-  0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74,
-  0x74, 0x61, 0x63, 0x6b, 0x2e, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73,
-  0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x73,
-  0x74, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69,
-  0x74, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65,
-  0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x65, 0x6e, 0x76,
-  0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72,
-  0x65, 0x20, 0x73, 0x75, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66,
-  0x6f, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61,
-  0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20,
-  0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x0a, 0x61, 0x63,
-  0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x76, 0x61, 0x6c, 0x75,
-  0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x20,
-  0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x6b, 0x65, 0x79, 0x73,
-  0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76,
-  0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e,
-  0x20, 0x54, 0x68, 0x65, 0x20, 0x67, 0x6f, 0x61, 0x6c, 0x20, 0x6f, 0x66,
-  0x20, 0x74, 0x68, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64,
-  0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x70, 0x72,
-  0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x69, 0x73, 0x0a, 0x74, 0x6f, 0x20,
-  0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x61, 0x20, 0x66, 0x72,
-  0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x77,
-  0x68, 0x69, 0x63, 0x68, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
-  0x79, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65,
-  0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62,
-  0x65, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x2c,
-  0x20, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20,
-  0x65, 0x61, 0x73, 0x69, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f,
-  0x79, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x0a, 0x72, 0x75, 0x6e, 0x20, 0x69,
-  0x6e, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65,
-  0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x65,
-  0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e,
-  0x20, 0x41, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20,
-  0x6f, 0x66, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x73,
-  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x35, 0x30,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x35, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41,
+  0x52, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd8, 0x81,
+  0xc4, 0x49, 0x3c, 0xe5, 0x73, 0xf5, 0x26, 0x5d, 0x90, 0x9e, 0xae, 0x06,
+  0x7f, 0x8a, 0x38, 0xd6, 0x51, 0xe5, 0xf5, 0xb9, 0x2e, 0xe9, 0x52, 0x00,
+  0x9b, 0x8a, 0x19, 0xf8, 0xcb, 0xa9, 0xb0, 0xb9, 0x7f, 0xae, 0xff, 0x03,
+  0x5d, 0xf2, 0x36, 0xa3, 0xfd, 0x58, 0x21, 0xc3, 0x10, 0x50, 0xfe, 0xff,
+  0x85, 0xbd, 0x79, 0x73, 0x8a, 0xb1, 0xa9, 0x1a, 0x87, 0x53, 0x7d, 0xd4,
+  0x3c, 0x46, 0x0e, 0x9a, 0x38, 0xca, 0xb0, 0x4e, 0xcd, 0xf6, 0x16, 0x60,
+  0x7c, 0xa0, 0x30, 0xc6, 0x1f, 0x41, 0xbe, 0x10, 0x54, 0x65, 0x27, 0xd3,
+  0x5c, 0x57, 0x6f, 0x60, 0xf6, 0x53, 0x1a, 0x17, 0xae, 0xdb, 0x17, 0xc6,
+  0x8f, 0x9d, 0xdc, 0x5f, 0xdc, 0xf0, 0x23, 0xba, 0xf1, 0xf0, 0xf8, 0x7d,
+  0xb6, 0x44, 0xa8, 0x9b, 0xf6, 0x61, 0xd7, 0xa5, 0x38, 0xd8, 0x71, 0xcb,
+  0x13, 0xe0, 0xd1, 0x35, 0x99, 0x1a, 0xbd, 0x4d, 0x89, 0x4b, 0x40, 0xa0,
+  0xca, 0xf4, 0x84, 0x01, 0xa7, 0xcc, 0xcd, 0xd0, 0xb7, 0xef, 0xb5, 0x9f,
+  0x48, 0x57, 0x19, 0x40, 0x6e, 0x5b, 0x51, 0x7c, 0xf5, 0x70, 0x48, 0x3b,
+  0xf9, 0x94, 0x5f, 0xc4, 0xc9, 0xce, 0x5a, 0xf7, 0x56, 0x3b, 0xa7, 0xa6,
+  0x0e, 0x73, 0x99, 0x7f, 0x97, 0x92, 0x40, 0x0d, 0x82, 0x50, 0x41, 0xf2,
+  0x8d, 0xe6, 0x0b, 0xa0, 0xfe, 0x1e, 0xfc, 0x66, 0xa5, 0x5c, 0x5c, 0xc2,
+  0xee, 0x4c, 0x41, 0x9e, 0xfc, 0xa1, 0x9c, 0xf3, 0xf6, 0xb7, 0xce, 0xaf,
+  0x3c, 0xb4, 0x32, 0x71, 0x2c, 0x0c, 0x5d, 0x69, 0x33, 0xbe, 0xca, 0xe9,
+  0x4d, 0x08, 0x14, 0xe9, 0x37, 0x48, 0x84, 0xda, 0x97, 0xd7, 0xec, 0xa2,
+  0xc3, 0x54, 0x66, 0x6a, 0x87, 0x28, 0xdd, 0x8d, 0x23, 0x47, 0x75, 0x0a,
+  0x76, 0x7e, 0xed, 0x72, 0x18, 0x20, 0xbf, 0xd4, 0x1b, 0xc7, 0x88, 0xd9,
+  0x74, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, 0x9d,
+  0xc8, 0x8c, 0x3c, 0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26,
+  0xb9, 0x80, 0x4b, 0xf2, 0x3b, 0x23, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x9d, 0xc8, 0x8c, 0x3c,
+  0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26, 0xb9, 0x80, 0x4b,
+  0xf2, 0x3b, 0x23, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x94, 0x47, 0x24, 0x8b, 0xfe, 0x3e, 0x28, 0xb1,
+  0x88, 0xed, 0x6c, 0x7f, 0x65, 0x48, 0xa6, 0x15, 0x0c, 0x47, 0xba, 0x9c,
+  0x90, 0x67, 0xf7, 0x5d, 0x64, 0x76, 0x61, 0x17, 0x81, 0x7b, 0xe0, 0x25,
+  0x4b, 0xe4, 0xfe, 0x9e, 0x76, 0x70, 0xe2, 0x19, 0x57, 0x22, 0x4e, 0x1e,
+  0x07, 0xc1, 0x4a, 0xc7, 0xe1, 0xc8, 0x57, 0xc9, 0x06, 0xe1, 0x6e, 0x8e,
+  0x12, 0xd7, 0xe5, 0x94, 0xc7, 0xa1, 0xdf, 0xcb, 0xcd, 0xe1, 0xac, 0x5c,
+  0xcf, 0x96, 0xf9, 0x1d, 0xdd, 0xb4, 0x02, 0x20, 0xdd, 0xa8, 0xc6, 0xae,
+  0x72, 0xd9, 0x2e, 0xc8, 0xe1, 0x07, 0x8d, 0xd4, 0x63, 0x00, 0x59, 0x26,
+  0x8d, 0x73, 0x36, 0x23, 0x36, 0xd4, 0x38, 0x42, 0xc2, 0x0a, 0xef, 0x68,
+  0x3e, 0x26, 0xff, 0x12, 0xaf, 0x5b, 0xf0, 0xa0, 0x8e, 0xb7, 0xce, 0xc1,
+  0x88, 0xc3, 0x9f, 0x50, 0x77, 0xa4, 0x44, 0x33, 0x9a, 0x44, 0x8e, 0x1b,
+  0x83, 0x80, 0xd4, 0xc9, 0xa6, 0x81, 0xfe, 0x87, 0x1f, 0x77, 0x04, 0x7f,
+  0x0f, 0xb4, 0x5e, 0x88, 0x40, 0x70, 0xd4, 0x3d, 0xeb, 0x96, 0xba, 0x15,
+  0xa8, 0x7a, 0x5a, 0x26, 0x6a, 0x36, 0xe4, 0x6b, 0x87, 0x11, 0x11, 0xc2,
+  0x3b, 0xa5, 0x50, 0x10, 0x5d, 0x3f, 0x00, 0xf4, 0x62, 0x37, 0x93, 0xee,
+  0x4b, 0x13, 0x38, 0xf5, 0xc7, 0x17, 0xef, 0x7f, 0xda, 0x10, 0x76, 0x9c,
+  0xc9, 0x2c, 0x11, 0xb4, 0xc2, 0x21, 0x8e, 0x72, 0x50, 0x9e, 0xf7, 0x98,
+  0x3c, 0x8e, 0xee, 0xa1, 0xd9, 0xf8, 0x46, 0x17, 0x89, 0x38, 0xaf, 0x59,
+  0xdb, 0x03, 0xd0, 0x50, 0x9e, 0x97, 0x1b, 0xf6, 0x7a, 0x15, 0x61, 0x24,
+  0xef, 0xa3, 0x9a, 0x7a, 0x0f, 0x05, 0x54, 0x22, 0x26, 0x93, 0x3d, 0xd7,
+  0x3b, 0x04, 0x1e, 0xe3, 0x13, 0xb7, 0xb0, 0xb1, 0x98, 0x8a, 0x6d, 0xfb,
+  0x11, 0x5e, 0x37, 0x29, 0x37, 0x54, 0x78, 0x42, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x02, 0x14, 0x44, 0x88, 0xdb, 0x5e,
+  0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe, 0x7d, 0x2c, 0xa2, 0xf6,
+  0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0xa2, 0x68, 0x2f, 0xb9, 0x5b, 0x09, 0x0b, 0xbb, 0x11, 0x34,
+  0xb5, 0x7e, 0xa1, 0x55, 0x1a, 0x9b, 0x04, 0xdc, 0x9d, 0xe8, 0x4b, 0xe8,
+  0x02, 0xda, 0x88, 0xe4, 0x81, 0xa9, 0x60, 0xae, 0x58, 0xb8, 0x43, 0x96,
+  0x6b, 0x9d, 0xd9, 0x01, 0x16, 0x52, 0x6b, 0x26, 0xa8, 0x18, 0x28, 0x5a,
+  0x0e, 0x1d, 0x7c, 0xc3, 0x5d, 0xef, 0xed, 0x1e, 0xf5, 0x35, 0x3c, 0xbe,
+  0xee, 0xff, 0x9e, 0xff, 0x29, 0x70, 0x00, 0x22, 0xea, 0x1b, 0x00, 0xf9,
+  0x6a, 0x8d, 0x05, 0x4a, 0x26, 0xe1, 0xcf, 0xc9, 0x56, 0x1c, 0xd4, 0x72,
+  0x8d, 0xab, 0x78, 0x35, 0xdf, 0xf5, 0xce, 0xed, 0x08, 0x9d, 0x62, 0x1f,
+  0x8f, 0xe3, 0x1c, 0x2b, 0xdd, 0x3a, 0x6b, 0x90, 0x90, 0x73, 0xf0, 0x9d,
+  0xb5, 0x37, 0xe4, 0x88, 0x78, 0x53, 0xd2, 0x22, 0x8e, 0x96, 0x76, 0x83,
+  0x0b, 0x3a, 0x96, 0x63, 0x25, 0x21, 0x6f, 0x09, 0x20, 0x7c, 0x27, 0xdf,
+  0xc3, 0x56, 0x61, 0x80, 0xb7, 0xfb, 0xf0, 0x83, 0x31, 0xa9, 0x57, 0x54,
+  0xec, 0xa0, 0x8f, 0xbc, 0x3e, 0xb4, 0x50, 0xe6, 0x84, 0x31, 0xda, 0x7b,
+  0xea, 0x1d, 0x6b, 0x54, 0xd9, 0x76, 0xc0, 0x06, 0xb9, 0xbf, 0x2f, 0xe8,
+  0x5d, 0x5d, 0x4d, 0xf0, 0x05, 0x68, 0xd3, 0x09, 0x35, 0x66, 0xbc, 0xcf,
+  0x39, 0x87, 0x9f, 0x09, 0x6b, 0x99, 0xa3, 0xb8, 0x33, 0xe2, 0x8f, 0x12,
+  0x92, 0xf9, 0x52, 0x1c, 0x07, 0xff, 0x1a, 0x35, 0x25, 0x6f, 0xc3, 0x71,
+  0x34, 0x38, 0xc5, 0xd1, 0x84, 0x0d, 0xca, 0xfa, 0x21, 0x98, 0xb6, 0xf9,
+  0x9c, 0xcb, 0xc2, 0xfe, 0x04, 0x53, 0xa8, 0xee, 0x88, 0x63, 0x71, 0xe5,
+  0xc2, 0x51, 0x1e, 0x78, 0x44, 0x62, 0xbf, 0x63, 0x52, 0x79, 0x7e, 0xe7,
+  0xb7, 0xd7, 0xff, 0x22, 0xb2, 0x2a, 0x82, 0x56, 0x60, 0xf9, 0x54, 0x76,
+  0x7b, 0x83, 0xb9, 0x36, 0xea, 0x25, 0x54, 0x68, 0x65, 0x20, 0x74, 0x65,
+  0x72, 0x6d, 0x20, 0x27, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20,
+  0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x27, 0x20, 0x69, 0x73, 0x20,
+  0x75, 0x73, 0x65, 0x64, 0x20, 0x61, 0x73, 0x20, 0x61, 0x20, 0x67, 0x65,
+  0x6e, 0x65, 0x72, 0x61, 0x6c, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x20, 0x66,
+  0x6f, 0x72, 0x20, 0x61, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6f,
+  0x66, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x72, 0x75, 0x6e, 0x73, 0x20,
+  0x69, 0x6e, 0x20, 0x61, 0x6e, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74,
+  0x65, 0x64, 0x0a, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e,
+  0x67, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e,
+  0x74, 0x2e, 0x20, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61, 0x70, 0x70,
+  0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72, 0x65,
+  0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65,
+  0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x74,
+  0x6f, 0x20, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x65,
+  0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74,
+  0x65, 0x64, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x73, 0x20, 0x69, 0x6e, 0x0a, 0x61, 0x20, 0x77, 0x61, 0x79, 0x20, 0x74,
+  0x68, 0x61, 0x74, 0x20, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x73, 0x20, 0x65,
+  0x78, 0x70, 0x6f, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x72,
+  0x65, 0x74, 0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x62, 0x65, 0x79, 0x6f,
+  0x6e, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61,
+  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72,
+  0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6e, 0x76,
+  0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x20, 0x54, 0x68,
+  0x65, 0x20, 0x77, 0x6f, 0x72, 0x64, 0x20, 0x27, 0x74, 0x72, 0x75, 0x73,
+  0x74, 0x65, 0x64, 0x27, 0x0a, 0x64, 0x6f, 0x65, 0x73, 0x20, 0x6e, 0x6f,
+  0x74, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x20, 0x61, 0x6e, 0x79, 0x74,
+  0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x6e, 0x68, 0x65, 0x72, 0x65, 0x6e,
+  0x74, 0x6c, 0x79, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x77, 0x6f, 0x72,
+  0x74, 0x68, 0x79, 0x20, 0x61, 0x62, 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20,
+  0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x61, 0x70, 0x70, 0x6c,
+  0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x62, 0x75, 0x74, 0x20,
+  0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20,
+  0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
+  0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x0a, 0x70, 0x75, 0x74, 0x20, 0x74,
+  0x72, 0x75, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20,
+  0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x20, 0x4d, 0x65, 0x65,
+  0x74, 0x69, 0x6e, 0x67, 0x20, 0x74, 0x68, 0x6f, 0x73, 0x65, 0x20, 0x74,
+  0x72, 0x75, 0x73, 0x74, 0x20, 0x6f, 0x62, 0x6c, 0x69, 0x67, 0x61, 0x74,
+  0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72, 0x65, 0x6c, 0x69, 0x65, 0x73, 0x20,
+  0x6f, 0x6e, 0x20, 0x61, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x20, 0x6f,
+  0x66, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x61,
+  0x6e, 0x64, 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x0a,
   0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20,
-  0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x62,
-  0x61, 0x73, 0x69, 0x63, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20,
-  0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x66, 0x75, 0x6e,
-  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20,
-  0x61, 0x73, 0x20, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, 0x61,
-  0x70, 0x68, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x63, 0x75,
-  0x72, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x0a,
-  0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x6f,
-  0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73,
-  0x73, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e,
-  0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x3a, 0x0a, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x53, 0x65, 0x63, 0x75,
-  0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
-  0x73, 0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65,
-  0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61,
-  0x74, 0x65, 0x64, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
-  0x65, 0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64,
-  0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65,
-  0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d,
-  0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d,
-  0x20, 0x2a, 0x2a, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61,
-  0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2a,
-  0x2a, 0x20, 0x2d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-  0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
-  0x65, 0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64,
-  0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x54, 0x45, 0x45, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x56, 0x4d, 0x20, 0x62, 0x61, 0x63,
-  0x6b, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
-  0x72, 0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69,
-  0x6e, 0x65, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x20,
-  0x74, 0x68, 0x61, 0x74, 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20,
-  0x68, 0x79, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x20, 0x74,
-  0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x68, 0x61,
-  0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x65,
-  0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20,
-  0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x0a, 0x54,
-  0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x72,
-  0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x73, 0x79, 0x73,
-  0x74, 0x65, 0x6d, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f,
-  0x72, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64,
-  0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20,
-  0x75, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x65, 0x63,
-  0x75, 0x72, 0x65, 0x20, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,
-  0x6e, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x20, 0x63, 0x6f,
-  0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a,
-  0x6f, 0x66, 0x20, 0x4f, 0x50, 0x2d, 0x54, 0x45, 0x45, 0x20, 0x74, 0x6f,
-  0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x20, 0x61, 0x20, 0x73, 0x65,
-  0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
-  0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72,
-  0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74, 0x20, 0x53, 0x2d,
-  0x45, 0x4c, 0x30, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63,
-  0x75, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,
-  0x6e, 0x73, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x73, 0x65, 0x72, 0x76,
-  0x69, 0x63, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72,
-  0x73, 0x0a, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65,
-  0x6d, 0x65, 0x6e, 0x74, 0x20, 0x50, 0x53, 0x41, 0x20, 0x72, 0x6f, 0x6f,
-  0x74, 0x2d, 0x6f, 0x66, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x73,
-  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x53, 0x65, 0x72,
-  0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65,
-  0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x75, 0x73,
-  0x69, 0x6e, 0x67, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x73,
-  0x69, 0x64, 0x65, 0x20, 0x43, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e,
-  0x67, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f,
-  0x73, 0x65, 0x20, 0x50, 0x53, 0x41, 0x0a, 0x46, 0x75, 0x6e, 0x63, 0x74,
-  0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20,
-  0x55, 0x45, 0x46, 0x49, 0x20, 0x53, 0x4d, 0x4d, 0x20, 0x73, 0x65, 0x72,
-  0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72,
-  0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68,
-  0x65, 0x20, 0x53, 0x4d, 0x4d, 0x20, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61,
-  0x79, 0x2e, 0x0a
+  0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x6d, 0x65, 0x61,
+  0x73, 0x75, 0x72, 0x65, 0x73, 0x2e, 0x0a
 };
-unsigned int VAR_auth_len = 3255;
+unsigned int VAR_auth_len = 1771;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/var_append.h b/components/service/uefi/smm_variable/test/service/auth_vectors/var_append.h
new file mode 100644
index 0000000..9b082a1
--- /dev/null
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/var_append.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file was generated by generate_auth_headers.sh
+ */
+
+unsigned char VAR_append_auth[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x44, 0x88, 0xdb, 0x5e, 0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe,
+  0x7d, 0x2c, 0xa2, 0xf6, 0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x35, 0x30,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x35, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41,
+  0x52, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd8, 0x81,
+  0xc4, 0x49, 0x3c, 0xe5, 0x73, 0xf5, 0x26, 0x5d, 0x90, 0x9e, 0xae, 0x06,
+  0x7f, 0x8a, 0x38, 0xd6, 0x51, 0xe5, 0xf5, 0xb9, 0x2e, 0xe9, 0x52, 0x00,
+  0x9b, 0x8a, 0x19, 0xf8, 0xcb, 0xa9, 0xb0, 0xb9, 0x7f, 0xae, 0xff, 0x03,
+  0x5d, 0xf2, 0x36, 0xa3, 0xfd, 0x58, 0x21, 0xc3, 0x10, 0x50, 0xfe, 0xff,
+  0x85, 0xbd, 0x79, 0x73, 0x8a, 0xb1, 0xa9, 0x1a, 0x87, 0x53, 0x7d, 0xd4,
+  0x3c, 0x46, 0x0e, 0x9a, 0x38, 0xca, 0xb0, 0x4e, 0xcd, 0xf6, 0x16, 0x60,
+  0x7c, 0xa0, 0x30, 0xc6, 0x1f, 0x41, 0xbe, 0x10, 0x54, 0x65, 0x27, 0xd3,
+  0x5c, 0x57, 0x6f, 0x60, 0xf6, 0x53, 0x1a, 0x17, 0xae, 0xdb, 0x17, 0xc6,
+  0x8f, 0x9d, 0xdc, 0x5f, 0xdc, 0xf0, 0x23, 0xba, 0xf1, 0xf0, 0xf8, 0x7d,
+  0xb6, 0x44, 0xa8, 0x9b, 0xf6, 0x61, 0xd7, 0xa5, 0x38, 0xd8, 0x71, 0xcb,
+  0x13, 0xe0, 0xd1, 0x35, 0x99, 0x1a, 0xbd, 0x4d, 0x89, 0x4b, 0x40, 0xa0,
+  0xca, 0xf4, 0x84, 0x01, 0xa7, 0xcc, 0xcd, 0xd0, 0xb7, 0xef, 0xb5, 0x9f,
+  0x48, 0x57, 0x19, 0x40, 0x6e, 0x5b, 0x51, 0x7c, 0xf5, 0x70, 0x48, 0x3b,
+  0xf9, 0x94, 0x5f, 0xc4, 0xc9, 0xce, 0x5a, 0xf7, 0x56, 0x3b, 0xa7, 0xa6,
+  0x0e, 0x73, 0x99, 0x7f, 0x97, 0x92, 0x40, 0x0d, 0x82, 0x50, 0x41, 0xf2,
+  0x8d, 0xe6, 0x0b, 0xa0, 0xfe, 0x1e, 0xfc, 0x66, 0xa5, 0x5c, 0x5c, 0xc2,
+  0xee, 0x4c, 0x41, 0x9e, 0xfc, 0xa1, 0x9c, 0xf3, 0xf6, 0xb7, 0xce, 0xaf,
+  0x3c, 0xb4, 0x32, 0x71, 0x2c, 0x0c, 0x5d, 0x69, 0x33, 0xbe, 0xca, 0xe9,
+  0x4d, 0x08, 0x14, 0xe9, 0x37, 0x48, 0x84, 0xda, 0x97, 0xd7, 0xec, 0xa2,
+  0xc3, 0x54, 0x66, 0x6a, 0x87, 0x28, 0xdd, 0x8d, 0x23, 0x47, 0x75, 0x0a,
+  0x76, 0x7e, 0xed, 0x72, 0x18, 0x20, 0xbf, 0xd4, 0x1b, 0xc7, 0x88, 0xd9,
+  0x74, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, 0x9d,
+  0xc8, 0x8c, 0x3c, 0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26,
+  0xb9, 0x80, 0x4b, 0xf2, 0x3b, 0x23, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x9d, 0xc8, 0x8c, 0x3c,
+  0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26, 0xb9, 0x80, 0x4b,
+  0xf2, 0x3b, 0x23, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x94, 0x47, 0x24, 0x8b, 0xfe, 0x3e, 0x28, 0xb1,
+  0x88, 0xed, 0x6c, 0x7f, 0x65, 0x48, 0xa6, 0x15, 0x0c, 0x47, 0xba, 0x9c,
+  0x90, 0x67, 0xf7, 0x5d, 0x64, 0x76, 0x61, 0x17, 0x81, 0x7b, 0xe0, 0x25,
+  0x4b, 0xe4, 0xfe, 0x9e, 0x76, 0x70, 0xe2, 0x19, 0x57, 0x22, 0x4e, 0x1e,
+  0x07, 0xc1, 0x4a, 0xc7, 0xe1, 0xc8, 0x57, 0xc9, 0x06, 0xe1, 0x6e, 0x8e,
+  0x12, 0xd7, 0xe5, 0x94, 0xc7, 0xa1, 0xdf, 0xcb, 0xcd, 0xe1, 0xac, 0x5c,
+  0xcf, 0x96, 0xf9, 0x1d, 0xdd, 0xb4, 0x02, 0x20, 0xdd, 0xa8, 0xc6, 0xae,
+  0x72, 0xd9, 0x2e, 0xc8, 0xe1, 0x07, 0x8d, 0xd4, 0x63, 0x00, 0x59, 0x26,
+  0x8d, 0x73, 0x36, 0x23, 0x36, 0xd4, 0x38, 0x42, 0xc2, 0x0a, 0xef, 0x68,
+  0x3e, 0x26, 0xff, 0x12, 0xaf, 0x5b, 0xf0, 0xa0, 0x8e, 0xb7, 0xce, 0xc1,
+  0x88, 0xc3, 0x9f, 0x50, 0x77, 0xa4, 0x44, 0x33, 0x9a, 0x44, 0x8e, 0x1b,
+  0x83, 0x80, 0xd4, 0xc9, 0xa6, 0x81, 0xfe, 0x87, 0x1f, 0x77, 0x04, 0x7f,
+  0x0f, 0xb4, 0x5e, 0x88, 0x40, 0x70, 0xd4, 0x3d, 0xeb, 0x96, 0xba, 0x15,
+  0xa8, 0x7a, 0x5a, 0x26, 0x6a, 0x36, 0xe4, 0x6b, 0x87, 0x11, 0x11, 0xc2,
+  0x3b, 0xa5, 0x50, 0x10, 0x5d, 0x3f, 0x00, 0xf4, 0x62, 0x37, 0x93, 0xee,
+  0x4b, 0x13, 0x38, 0xf5, 0xc7, 0x17, 0xef, 0x7f, 0xda, 0x10, 0x76, 0x9c,
+  0xc9, 0x2c, 0x11, 0xb4, 0xc2, 0x21, 0x8e, 0x72, 0x50, 0x9e, 0xf7, 0x98,
+  0x3c, 0x8e, 0xee, 0xa1, 0xd9, 0xf8, 0x46, 0x17, 0x89, 0x38, 0xaf, 0x59,
+  0xdb, 0x03, 0xd0, 0x50, 0x9e, 0x97, 0x1b, 0xf6, 0x7a, 0x15, 0x61, 0x24,
+  0xef, 0xa3, 0x9a, 0x7a, 0x0f, 0x05, 0x54, 0x22, 0x26, 0x93, 0x3d, 0xd7,
+  0x3b, 0x04, 0x1e, 0xe3, 0x13, 0xb7, 0xb0, 0xb1, 0x98, 0x8a, 0x6d, 0xfb,
+  0x11, 0x5e, 0x37, 0x29, 0x37, 0x54, 0x78, 0x42, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x02, 0x14, 0x44, 0x88, 0xdb, 0x5e,
+  0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe, 0x7d, 0x2c, 0xa2, 0xf6,
+  0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0xb0, 0x9b, 0x24, 0xea, 0xd3, 0x56, 0x58, 0x5d, 0xfe, 0xb5,
+  0x2f, 0xf4, 0x8e, 0xeb, 0x66, 0x7b, 0xa0, 0x48, 0xf9, 0x6e, 0x1e, 0x49,
+  0x51, 0xcc, 0xb5, 0xef, 0xb3, 0x5f, 0x2c, 0x60, 0x11, 0x39, 0x74, 0x6f,
+  0x62, 0xe2, 0x32, 0x93, 0xbd, 0xa1, 0x39, 0x22, 0xa0, 0x9f, 0xe9, 0xfc,
+  0xc3, 0x89, 0x44, 0x69, 0x7d, 0xdd, 0xd9, 0xe6, 0x22, 0x97, 0x22, 0x60,
+  0xd8, 0xca, 0x2f, 0x49, 0x86, 0x43, 0xdf, 0xb5, 0xff, 0x6f, 0x1c, 0xa0,
+  0x7d, 0x8c, 0x8b, 0x00, 0xec, 0xb2, 0x95, 0xe5, 0xb6, 0xbf, 0x63, 0xbb,
+  0x42, 0x5e, 0xf9, 0x09, 0xa1, 0xfc, 0x78, 0x08, 0xa1, 0x9f, 0x6c, 0x7a,
+  0x46, 0xe9, 0x34, 0x17, 0x94, 0xb1, 0x74, 0x47, 0x79, 0x51, 0x35, 0xf1,
+  0x8e, 0xe1, 0x02, 0x00, 0xdf, 0xb5, 0x39, 0x43, 0x28, 0xc1, 0x0a, 0x5b,
+  0x04, 0xdd, 0x0b, 0x32, 0xaa, 0x0b, 0x84, 0x96, 0xfe, 0xeb, 0xa2, 0x85,
+  0x6a, 0xe0, 0x18, 0xd8, 0x75, 0x11, 0xa4, 0xf0, 0x29, 0xbd, 0x3d, 0xfd,
+  0xa8, 0xa7, 0x41, 0x62, 0xa8, 0x4e, 0x56, 0xf5, 0x88, 0xf6, 0x66, 0xe7,
+  0xbc, 0x97, 0x10, 0xd7, 0x21, 0x56, 0x92, 0x6f, 0x18, 0x08, 0xb4, 0x7d,
+  0xf9, 0x5d, 0x28, 0x59, 0x37, 0x92, 0x25, 0xa9, 0x3f, 0x2d, 0x78, 0x3c,
+  0x9e, 0x58, 0xea, 0x4e, 0x73, 0x84, 0xad, 0xe3, 0x86, 0xe5, 0x63, 0xd9,
+  0xf3, 0xed, 0xa7, 0xdc, 0x20, 0x8c, 0xa8, 0x31, 0x8a, 0xe4, 0x01, 0x16,
+  0xee, 0xf5, 0xcf, 0x60, 0xf7, 0xa3, 0x58, 0xd0, 0x21, 0xac, 0x63, 0x23,
+  0x01, 0xea, 0x26, 0x7f, 0xe5, 0x65, 0xe3, 0x00, 0xbb, 0xd6, 0xff, 0xa9,
+  0x8d, 0x2a, 0x87, 0x3c, 0xc6, 0xcc, 0x26, 0x51, 0x45, 0x45, 0xac, 0x07,
+  0x0b, 0x98, 0x9c, 0x04, 0x45, 0x71, 0x49, 0xfc, 0xb6, 0x22, 0x27, 0xd6,
+  0x53, 0xa0, 0xc5, 0x82, 0x35, 0x8e, 0x54, 0x68, 0x65, 0x20, 0x41, 0x72,
+  0x6d, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x41,
+  0x2d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x29, 0x20, 0x61, 0x72,
+  0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20,
+  0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x74, 0x61, 0x6e,
+  0x64, 0x61, 0x72, 0x64, 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72,
+  0x65, 0x2c, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20,
+  0x61, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x0a, 0x6f, 0x66, 0x20, 0x69,
+  0x73, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x63,
+  0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72,
+  0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74,
+  0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77,
+  0x61, 0x72, 0x65, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x70,
+  0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x67,
+  0x61, 0x69, 0x6e, 0x73, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75,
+  0x73, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66,
+  0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x0a, 0x42, 0x65, 0x63,
+  0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69,
+  0x72, 0x20, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63,
+  0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72,
+  0x74, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20,
+  0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73,
+  0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x75, 0x69, 0x74, 0x61, 0x62, 0x6c,
+  0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
+  0x67, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65,
+  0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x76,
+  0x61, 0x6c, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x73, 0x73, 0x65,
+  0x74, 0x73, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x6b,
+  0x65, 0x79, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6e, 0x73, 0x69,
+  0x74, 0x69, 0x76, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x61,
+  0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x67, 0x6f, 0x61, 0x6c,
+  0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73,
+  0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+  0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x69, 0x73, 0x0a,
+  0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x61,
+  0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69,
+  0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x73, 0x65, 0x63, 0x75,
+  0x72, 0x69, 0x74, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64,
+  0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61,
+  0x79, 0x20, 0x62, 0x65, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70,
+  0x65, 0x64, 0x2c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61,
+  0x6e, 0x64, 0x20, 0x65, 0x61, 0x73, 0x69, 0x6c, 0x79, 0x20, 0x64, 0x65,
+  0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x0a, 0x72, 0x75,
+  0x6e, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20,
+  0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65,
+  0x64, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e,
+  0x74, 0x73, 0x2e, 0x20, 0x41, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x73,
+  0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65,
+  0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61,
+  0x72, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+  0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
+  0x65, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x0a, 0x64, 0x65, 0x76, 0x69,
+  0x63, 0x65, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20,
+  0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x73, 0x75,
+  0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f,
+  0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73,
+  0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
+  0x65, 0x2e, 0x0a, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20,
+  0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f,
+  0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76, 0x69,
+  0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65,
+  0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x53,
+  0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74,
+  0x69, 0x6f, 0x6e, 0x73, 0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x63,
+  0x75, 0x72, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x69, 0x73,
+  0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72,
+  0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61,
+  0x67, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x73, 0x65, 0x63,
+  0x75, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65,
+  0x64, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x73, 0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69,
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72,
+  0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61,
+  0x67, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x54, 0x45, 0x45,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x56, 0x4d, 0x20,
+  0x62, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61,
+  0x69, 0x6e, 0x65, 0x72, 0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x6e,
+  0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x74, 0x69,
+  0x6d, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x75, 0x73, 0x65, 0x73,
+  0x20, 0x61, 0x20, 0x68, 0x79, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f,
+  0x72, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
+  0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x62, 0x61,
+  0x63, 0x6b, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
+  0x65, 0x72, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
+  0x74, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20,
+  0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x64,
+  0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x61, 0x6e,
+  0x64, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e,
+  0x74, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+  0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x50, 0x61, 0x72, 0x74, 0x69,
+  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
+  0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x0a, 0x6f, 0x66, 0x20, 0x4f, 0x50, 0x2d, 0x54, 0x45, 0x45,
+  0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x20, 0x61,
+  0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, 0x75,
+  0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+  0x73, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74,
+  0x20, 0x53, 0x2d, 0x45, 0x4c, 0x30, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20,
+  0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69,
+  0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x73,
+  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69,
+  0x64, 0x65, 0x72, 0x73, 0x0a, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x6d,
+  0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x50, 0x53, 0x41, 0x20,
+  0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x6f, 0x66, 0x2d, 0x74, 0x72, 0x75, 0x73,
+  0x74, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x20,
+  0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79,
+  0x20, 0x62, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64,
+  0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+  0x74, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x20, 0x43, 0x20, 0x62, 0x69, 0x6e,
+  0x64, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x65,
+  0x78, 0x70, 0x6f, 0x73, 0x65, 0x20, 0x50, 0x53, 0x41, 0x0a, 0x46, 0x75,
+  0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x41, 0x50, 0x49,
+  0x73, 0x2e, 0x20, 0x55, 0x45, 0x46, 0x49, 0x20, 0x53, 0x4d, 0x4d, 0x20,
+  0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65,
+  0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79,
+  0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x4d, 0x4d, 0x20, 0x47, 0x61, 0x74,
+  0x65, 0x77, 0x61, 0x79, 0x2e, 0x0a
+};
+unsigned int VAR_append_auth_len = 2670;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/var_append_old.h b/components/service/uefi/smm_variable/test/service/auth_vectors/var_append_old.h
new file mode 100644
index 0000000..570509a
--- /dev/null
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/var_append_old.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file was generated by generate_auth_headers.sh
+ */
+
+unsigned char VAR_append_old_auth[] = {
+  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x44, 0x88, 0xdb, 0x5e, 0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe,
+  0x7d, 0x2c, 0xa2, 0xf6, 0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x35, 0x30,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x35, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41,
+  0x52, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd8, 0x81,
+  0xc4, 0x49, 0x3c, 0xe5, 0x73, 0xf5, 0x26, 0x5d, 0x90, 0x9e, 0xae, 0x06,
+  0x7f, 0x8a, 0x38, 0xd6, 0x51, 0xe5, 0xf5, 0xb9, 0x2e, 0xe9, 0x52, 0x00,
+  0x9b, 0x8a, 0x19, 0xf8, 0xcb, 0xa9, 0xb0, 0xb9, 0x7f, 0xae, 0xff, 0x03,
+  0x5d, 0xf2, 0x36, 0xa3, 0xfd, 0x58, 0x21, 0xc3, 0x10, 0x50, 0xfe, 0xff,
+  0x85, 0xbd, 0x79, 0x73, 0x8a, 0xb1, 0xa9, 0x1a, 0x87, 0x53, 0x7d, 0xd4,
+  0x3c, 0x46, 0x0e, 0x9a, 0x38, 0xca, 0xb0, 0x4e, 0xcd, 0xf6, 0x16, 0x60,
+  0x7c, 0xa0, 0x30, 0xc6, 0x1f, 0x41, 0xbe, 0x10, 0x54, 0x65, 0x27, 0xd3,
+  0x5c, 0x57, 0x6f, 0x60, 0xf6, 0x53, 0x1a, 0x17, 0xae, 0xdb, 0x17, 0xc6,
+  0x8f, 0x9d, 0xdc, 0x5f, 0xdc, 0xf0, 0x23, 0xba, 0xf1, 0xf0, 0xf8, 0x7d,
+  0xb6, 0x44, 0xa8, 0x9b, 0xf6, 0x61, 0xd7, 0xa5, 0x38, 0xd8, 0x71, 0xcb,
+  0x13, 0xe0, 0xd1, 0x35, 0x99, 0x1a, 0xbd, 0x4d, 0x89, 0x4b, 0x40, 0xa0,
+  0xca, 0xf4, 0x84, 0x01, 0xa7, 0xcc, 0xcd, 0xd0, 0xb7, 0xef, 0xb5, 0x9f,
+  0x48, 0x57, 0x19, 0x40, 0x6e, 0x5b, 0x51, 0x7c, 0xf5, 0x70, 0x48, 0x3b,
+  0xf9, 0x94, 0x5f, 0xc4, 0xc9, 0xce, 0x5a, 0xf7, 0x56, 0x3b, 0xa7, 0xa6,
+  0x0e, 0x73, 0x99, 0x7f, 0x97, 0x92, 0x40, 0x0d, 0x82, 0x50, 0x41, 0xf2,
+  0x8d, 0xe6, 0x0b, 0xa0, 0xfe, 0x1e, 0xfc, 0x66, 0xa5, 0x5c, 0x5c, 0xc2,
+  0xee, 0x4c, 0x41, 0x9e, 0xfc, 0xa1, 0x9c, 0xf3, 0xf6, 0xb7, 0xce, 0xaf,
+  0x3c, 0xb4, 0x32, 0x71, 0x2c, 0x0c, 0x5d, 0x69, 0x33, 0xbe, 0xca, 0xe9,
+  0x4d, 0x08, 0x14, 0xe9, 0x37, 0x48, 0x84, 0xda, 0x97, 0xd7, 0xec, 0xa2,
+  0xc3, 0x54, 0x66, 0x6a, 0x87, 0x28, 0xdd, 0x8d, 0x23, 0x47, 0x75, 0x0a,
+  0x76, 0x7e, 0xed, 0x72, 0x18, 0x20, 0xbf, 0xd4, 0x1b, 0xc7, 0x88, 0xd9,
+  0x74, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, 0x9d,
+  0xc8, 0x8c, 0x3c, 0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26,
+  0xb9, 0x80, 0x4b, 0xf2, 0x3b, 0x23, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x9d, 0xc8, 0x8c, 0x3c,
+  0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26, 0xb9, 0x80, 0x4b,
+  0xf2, 0x3b, 0x23, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x94, 0x47, 0x24, 0x8b, 0xfe, 0x3e, 0x28, 0xb1,
+  0x88, 0xed, 0x6c, 0x7f, 0x65, 0x48, 0xa6, 0x15, 0x0c, 0x47, 0xba, 0x9c,
+  0x90, 0x67, 0xf7, 0x5d, 0x64, 0x76, 0x61, 0x17, 0x81, 0x7b, 0xe0, 0x25,
+  0x4b, 0xe4, 0xfe, 0x9e, 0x76, 0x70, 0xe2, 0x19, 0x57, 0x22, 0x4e, 0x1e,
+  0x07, 0xc1, 0x4a, 0xc7, 0xe1, 0xc8, 0x57, 0xc9, 0x06, 0xe1, 0x6e, 0x8e,
+  0x12, 0xd7, 0xe5, 0x94, 0xc7, 0xa1, 0xdf, 0xcb, 0xcd, 0xe1, 0xac, 0x5c,
+  0xcf, 0x96, 0xf9, 0x1d, 0xdd, 0xb4, 0x02, 0x20, 0xdd, 0xa8, 0xc6, 0xae,
+  0x72, 0xd9, 0x2e, 0xc8, 0xe1, 0x07, 0x8d, 0xd4, 0x63, 0x00, 0x59, 0x26,
+  0x8d, 0x73, 0x36, 0x23, 0x36, 0xd4, 0x38, 0x42, 0xc2, 0x0a, 0xef, 0x68,
+  0x3e, 0x26, 0xff, 0x12, 0xaf, 0x5b, 0xf0, 0xa0, 0x8e, 0xb7, 0xce, 0xc1,
+  0x88, 0xc3, 0x9f, 0x50, 0x77, 0xa4, 0x44, 0x33, 0x9a, 0x44, 0x8e, 0x1b,
+  0x83, 0x80, 0xd4, 0xc9, 0xa6, 0x81, 0xfe, 0x87, 0x1f, 0x77, 0x04, 0x7f,
+  0x0f, 0xb4, 0x5e, 0x88, 0x40, 0x70, 0xd4, 0x3d, 0xeb, 0x96, 0xba, 0x15,
+  0xa8, 0x7a, 0x5a, 0x26, 0x6a, 0x36, 0xe4, 0x6b, 0x87, 0x11, 0x11, 0xc2,
+  0x3b, 0xa5, 0x50, 0x10, 0x5d, 0x3f, 0x00, 0xf4, 0x62, 0x37, 0x93, 0xee,
+  0x4b, 0x13, 0x38, 0xf5, 0xc7, 0x17, 0xef, 0x7f, 0xda, 0x10, 0x76, 0x9c,
+  0xc9, 0x2c, 0x11, 0xb4, 0xc2, 0x21, 0x8e, 0x72, 0x50, 0x9e, 0xf7, 0x98,
+  0x3c, 0x8e, 0xee, 0xa1, 0xd9, 0xf8, 0x46, 0x17, 0x89, 0x38, 0xaf, 0x59,
+  0xdb, 0x03, 0xd0, 0x50, 0x9e, 0x97, 0x1b, 0xf6, 0x7a, 0x15, 0x61, 0x24,
+  0xef, 0xa3, 0x9a, 0x7a, 0x0f, 0x05, 0x54, 0x22, 0x26, 0x93, 0x3d, 0xd7,
+  0x3b, 0x04, 0x1e, 0xe3, 0x13, 0xb7, 0xb0, 0xb1, 0x98, 0x8a, 0x6d, 0xfb,
+  0x11, 0x5e, 0x37, 0x29, 0x37, 0x54, 0x78, 0x42, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x02, 0x14, 0x44, 0x88, 0xdb, 0x5e,
+  0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe, 0x7d, 0x2c, 0xa2, 0xf6,
+  0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x7a, 0xed, 0x63, 0x59, 0xf6, 0xc3, 0x19, 0xf6, 0xfc, 0x35,
+  0xf6, 0x4d, 0xd4, 0x2d, 0xe7, 0x7d, 0xc2, 0xd3, 0x16, 0x22, 0x2a, 0x8d,
+  0x8e, 0x62, 0x66, 0x6d, 0xa3, 0x21, 0x9f, 0xfc, 0x5f, 0x9a, 0x43, 0x81,
+  0xef, 0xd7, 0x6d, 0x06, 0xe2, 0x9c, 0x3c, 0x26, 0xa6, 0x87, 0x87, 0x5f,
+  0x6b, 0x46, 0xc0, 0x93, 0xf3, 0x8c, 0x41, 0x82, 0x52, 0x94, 0x22, 0x8b,
+  0x8e, 0x98, 0x09, 0x9a, 0xb1, 0xd6, 0xfe, 0x5d, 0x63, 0xa5, 0xd2, 0x27,
+  0x93, 0x1d, 0x14, 0x5f, 0x32, 0xbe, 0x08, 0xbe, 0xb9, 0x76, 0x04, 0xb8,
+  0xe3, 0x74, 0x3b, 0x40, 0x6c, 0xdd, 0x52, 0xa2, 0x6c, 0x14, 0xbb, 0xc3,
+  0x46, 0xce, 0x62, 0x3a, 0x64, 0x5e, 0x2f, 0x4b, 0xd6, 0x1a, 0x6f, 0x06,
+  0xac, 0xaa, 0xd0, 0x1b, 0x86, 0x78, 0x08, 0xa6, 0xae, 0x82, 0xf0, 0xfd,
+  0xd1, 0xdf, 0x69, 0x6c, 0xf0, 0x00, 0x5c, 0xef, 0x64, 0xd8, 0xb1, 0x11,
+  0x7d, 0xf7, 0x7e, 0xcc, 0xdc, 0x81, 0x73, 0x5b, 0x2d, 0x8e, 0x38, 0x8f,
+  0x39, 0xfd, 0xad, 0xc2, 0xaa, 0xb0, 0x7e, 0x7f, 0x52, 0xd2, 0x43, 0x09,
+  0xbb, 0x10, 0x09, 0x14, 0x57, 0xf2, 0x33, 0x99, 0xd5, 0x56, 0xc2, 0x19,
+  0xc6, 0x61, 0xac, 0xfa, 0xe5, 0x50, 0x3a, 0x51, 0xb8, 0x7b, 0x27, 0xb8,
+  0x1e, 0xe0, 0x31, 0xa8, 0x7b, 0x7a, 0x52, 0x82, 0x11, 0x00, 0xf5, 0x5b,
+  0xb6, 0x1f, 0x51, 0x9a, 0x64, 0xe2, 0x42, 0xa1, 0x1a, 0x88, 0x01, 0x48,
+  0xc8, 0x34, 0xcd, 0x59, 0x1e, 0xb1, 0x1e, 0x93, 0x0e, 0x77, 0x41, 0xf9,
+  0xdb, 0x75, 0x7c, 0x6e, 0xe1, 0x76, 0xb0, 0xec, 0xc8, 0xbd, 0xb4, 0x2b,
+  0x6b, 0x97, 0xff, 0x7b, 0xcd, 0xaa, 0xe1, 0x34, 0x1d, 0xb1, 0x46, 0xbe,
+  0x60, 0x4f, 0xf7, 0x39, 0x06, 0xa4, 0x58, 0xcb, 0x1a, 0x79, 0x6f, 0x63,
+  0x0a, 0x2c, 0xf1, 0x55, 0xcd, 0x8b, 0x54, 0x68, 0x65, 0x20, 0x41, 0x72,
+  0x6d, 0x20, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x2d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x41,
+  0x2d, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x29, 0x20, 0x61, 0x72,
+  0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20,
+  0x69, 0x6e, 0x20, 0x63, 0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x73, 0x74, 0x61, 0x6e,
+  0x64, 0x61, 0x72, 0x64, 0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72,
+  0x65, 0x2c, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20,
+  0x61, 0x20, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x0a, 0x6f, 0x66, 0x20, 0x69,
+  0x73, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x63,
+  0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72,
+  0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74,
+  0x20, 0x6f, 0x66, 0x66, 0x65, 0x72, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77,
+  0x61, 0x72, 0x65, 0x2d, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x70,
+  0x72, 0x6f, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x67,
+  0x61, 0x69, 0x6e, 0x73, 0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75,
+  0x73, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66,
+  0x20, 0x61, 0x74, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x0a, 0x42, 0x65, 0x63,
+  0x61, 0x75, 0x73, 0x65, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69,
+  0x72, 0x20, 0x73, 0x74, 0x72, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63,
+  0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72,
+  0x74, 0x69, 0x65, 0x73, 0x2c, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20,
+  0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73,
+  0x20, 0x61, 0x72, 0x65, 0x20, 0x73, 0x75, 0x69, 0x74, 0x61, 0x62, 0x6c,
+  0x65, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e,
+  0x67, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65,
+  0x0a, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x76,
+  0x61, 0x6c, 0x75, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x61, 0x73, 0x73, 0x65,
+  0x74, 0x73, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x6b,
+  0x65, 0x79, 0x73, 0x20, 0x6f, 0x72, 0x20, 0x73, 0x65, 0x6e, 0x73, 0x69,
+  0x74, 0x69, 0x76, 0x65, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x61,
+  0x74, 0x61, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x67, 0x6f, 0x61, 0x6c,
+  0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73,
+  0x74, 0x65, 0x64, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
+  0x20, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x20, 0x69, 0x73, 0x0a,
+  0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x61,
+  0x20, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69,
+  0x6e, 0x20, 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x73, 0x65, 0x63, 0x75,
+  0x72, 0x69, 0x74, 0x79, 0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64,
+  0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61,
+  0x79, 0x20, 0x62, 0x65, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70,
+  0x65, 0x64, 0x2c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61,
+  0x6e, 0x64, 0x20, 0x65, 0x61, 0x73, 0x69, 0x6c, 0x79, 0x20, 0x64, 0x65,
+  0x70, 0x6c, 0x6f, 0x79, 0x65, 0x64, 0x20, 0x74, 0x6f, 0x0a, 0x72, 0x75,
+  0x6e, 0x20, 0x69, 0x6e, 0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20,
+  0x74, 0x68, 0x65, 0x20, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65,
+  0x64, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e,
+  0x74, 0x73, 0x2e, 0x20, 0x41, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x73,
+  0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65,
+  0x64, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61,
+  0x72, 0x65, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74,
+  0x65, 0x64, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64,
+  0x65, 0x20, 0x62, 0x61, 0x73, 0x69, 0x63, 0x0a, 0x64, 0x65, 0x76, 0x69,
+  0x63, 0x65, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20,
+  0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x73, 0x75,
+  0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f,
+  0x67, 0x72, 0x61, 0x70, 0x68, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73,
+  0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
+  0x65, 0x2e, 0x0a, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20,
+  0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f,
+  0x63, 0x65, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76, 0x69,
+  0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65,
+  0x3a, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x53,
+  0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74,
+  0x69, 0x6f, 0x6e, 0x73, 0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x63,
+  0x75, 0x72, 0x65, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x69, 0x73,
+  0x6f, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72,
+  0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61,
+  0x67, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x73, 0x65, 0x63,
+  0x75, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65,
+  0x64, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x73, 0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69,
+  0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72,
+  0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61,
+  0x67, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x61, 0x20, 0x54, 0x45, 0x45,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x56, 0x4d, 0x20,
+  0x62, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61,
+  0x69, 0x6e, 0x65, 0x72, 0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x6e,
+  0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x74, 0x69,
+  0x6d, 0x65, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x75, 0x73, 0x65, 0x73,
+  0x20, 0x61, 0x20, 0x68, 0x79, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f,
+  0x72, 0x20, 0x74, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
+  0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x62, 0x61,
+  0x63, 0x6b, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
+  0x65, 0x72, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e,
+  0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c,
+  0x74, 0x20, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20,
+  0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x64,
+  0x20, 0x66, 0x6f, 0x72, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x61, 0x6e,
+  0x64, 0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e,
+  0x74, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20,
+  0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x50, 0x61, 0x72, 0x74, 0x69,
+  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72,
+  0x20, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69,
+  0x6f, 0x6e, 0x0a, 0x6f, 0x66, 0x20, 0x4f, 0x50, 0x2d, 0x54, 0x45, 0x45,
+  0x20, 0x74, 0x6f, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x20, 0x61,
+  0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, 0x75,
+  0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
+  0x73, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74,
+  0x20, 0x53, 0x2d, 0x45, 0x4c, 0x30, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20,
+  0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69,
+  0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x73,
+  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69,
+  0x64, 0x65, 0x72, 0x73, 0x0a, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x6d,
+  0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x20, 0x50, 0x53, 0x41, 0x20,
+  0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x6f, 0x66, 0x2d, 0x74, 0x72, 0x75, 0x73,
+  0x74, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x20,
+  0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79,
+  0x20, 0x62, 0x65, 0x20, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64,
+  0x20, 0x75, 0x73, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e,
+  0x74, 0x2d, 0x73, 0x69, 0x64, 0x65, 0x20, 0x43, 0x20, 0x62, 0x69, 0x6e,
+  0x64, 0x69, 0x6e, 0x67, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x65,
+  0x78, 0x70, 0x6f, 0x73, 0x65, 0x20, 0x50, 0x53, 0x41, 0x0a, 0x46, 0x75,
+  0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x41, 0x50, 0x49,
+  0x73, 0x2e, 0x20, 0x55, 0x45, 0x46, 0x49, 0x20, 0x53, 0x4d, 0x4d, 0x20,
+  0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65,
+  0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79,
+  0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x4d, 0x4d, 0x20, 0x47, 0x61, 0x74,
+  0x65, 0x77, 0x61, 0x79, 0x2e, 0x0a
+};
+unsigned int VAR_append_old_auth_len = 2670;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/var_data.h b/components/service/uefi/smm_variable/test/service/auth_vectors/var_data.h
index 32d7072..3734425 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/var_data.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/var_data.h
@@ -54,128 +54,128 @@
   0x6d, 0x77, 0x61, 0x72, 0x65, 0x0a, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d,
   0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69,
   0x74, 0x79, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x73, 0x2e,
-  0x0a, 0x0a, 0x54, 0x68, 0x65, 0x20, 0x41, 0x72, 0x6d, 0x20, 0x41, 0x70,
-  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x70, 0x72,
-  0x6f, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x41, 0x2d, 0x70, 0x72, 0x6f,
-  0x66, 0x69, 0x6c, 0x65, 0x29, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74,
-  0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x63,
-  0x6f, 0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77,
-  0x69, 0x74, 0x68, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64,
-  0x20, 0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2c, 0x20, 0x70,
-  0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20, 0x61, 0x20, 0x72, 0x61,
-  0x6e, 0x67, 0x65, 0x0a, 0x6f, 0x66, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61,
+  0x0a, 0x54, 0x68, 0x65, 0x20, 0x41, 0x72, 0x6d, 0x20, 0x41, 0x70, 0x70,
+  0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2d, 0x70, 0x72, 0x6f,
+  0x66, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x41, 0x2d, 0x70, 0x72, 0x6f, 0x66,
+  0x69, 0x6c, 0x65, 0x29, 0x20, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65,
+  0x63, 0x74, 0x75, 0x72, 0x65, 0x2c, 0x20, 0x69, 0x6e, 0x20, 0x63, 0x6f,
+  0x6d, 0x62, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77, 0x69,
+  0x74, 0x68, 0x20, 0x73, 0x74, 0x61, 0x6e, 0x64, 0x61, 0x72, 0x64, 0x20,
+  0x66, 0x69, 0x72, 0x6d, 0x77, 0x61, 0x72, 0x65, 0x2c, 0x20, 0x70, 0x72,
+  0x6f, 0x76, 0x69, 0x64, 0x65, 0x73, 0x20, 0x61, 0x20, 0x72, 0x61, 0x6e,
+  0x67, 0x65, 0x0a, 0x6f, 0x66, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74,
+  0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69, 0x6e,
+  0x67, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e,
+  0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x66, 0x66, 0x65,
+  0x72, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2d, 0x62,
+  0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65, 0x63,
+  0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x73, 0x74,
+  0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x63, 0x6c, 0x61,
+  0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x74, 0x61,
+  0x63, 0x6b, 0x2e, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65, 0x20,
+  0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x73, 0x74, 0x72,
+  0x6f, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
+  0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x2c,
+  0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72,
+  0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20,
+  0x73, 0x75, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f, 0x72,
+  0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x70, 0x70,
+  0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74, 0x68,
+  0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x0a, 0x61, 0x63, 0x63, 0x65,
+  0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x61, 0x62,
+  0x6c, 0x65, 0x20, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x20, 0x73, 0x75,
+  0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x20, 0x6f,
+  0x72, 0x20, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x20,
+  0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x20, 0x54,
+  0x68, 0x65, 0x20, 0x67, 0x6f, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x74,
+  0x68, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x53,
+  0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x6a,
+  0x65, 0x63, 0x74, 0x20, 0x69, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x70, 0x72,
+  0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x61, 0x20, 0x66, 0x72, 0x61, 0x6d,
+  0x65, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68, 0x69,
+  0x63, 0x68, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20,
+  0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65, 0x72, 0x76,
+  0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20,
+  0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x2c, 0x20, 0x74,
+  0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65, 0x61,
+  0x73, 0x69, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x65,
+  0x64, 0x20, 0x74, 0x6f, 0x0a, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20,
+  0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73,
+  0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x65, 0x6e, 0x76,
+  0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x41,
+  0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f, 0x66,
+  0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65, 0x72,
+  0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x69, 0x6d,
+  0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x74, 0x6f,
+  0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x62, 0x61, 0x73,
+  0x69, 0x63, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x73, 0x65,
+  0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74,
+  0x69, 0x6f, 0x6e, 0x73, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61, 0x73,
+  0x20, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x70, 0x68,
+  0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65,
+  0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x0a, 0x0a, 0x45,
+  0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61,
   0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x69,
   0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65,
-  0x6e, 0x74, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x6f, 0x66, 0x66,
-  0x65, 0x72, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x2d,
-  0x62, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x74, 0x65,
-  0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e, 0x73,
-  0x74, 0x20, 0x76, 0x61, 0x72, 0x69, 0x6f, 0x75, 0x73, 0x20, 0x63, 0x6c,
-  0x61, 0x73, 0x73, 0x65, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x61, 0x74, 0x74,
-  0x61, 0x63, 0x6b, 0x2e, 0x0a, 0x42, 0x65, 0x63, 0x61, 0x75, 0x73, 0x65,
-  0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x69, 0x72, 0x20, 0x73, 0x74,
-  0x72, 0x6f, 0x6e, 0x67, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74,
-  0x79, 0x20, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73,
-  0x2c, 0x20, 0x74, 0x68, 0x65, 0x73, 0x65, 0x20, 0x65, 0x6e, 0x76, 0x69,
-  0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65,
-  0x20, 0x73, 0x75, 0x69, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x66, 0x6f,
-  0x72, 0x20, 0x72, 0x75, 0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x70,
-  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x74,
-  0x68, 0x61, 0x74, 0x20, 0x68, 0x61, 0x76, 0x65, 0x0a, 0x61, 0x63, 0x63,
-  0x65, 0x73, 0x73, 0x20, 0x74, 0x6f, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x61,
-  0x62, 0x6c, 0x65, 0x20, 0x61, 0x73, 0x73, 0x65, 0x74, 0x73, 0x20, 0x73,
-  0x75, 0x63, 0x68, 0x20, 0x61, 0x73, 0x20, 0x6b, 0x65, 0x79, 0x73, 0x20,
-  0x6f, 0x72, 0x20, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65,
-  0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x20,
-  0x54, 0x68, 0x65, 0x20, 0x67, 0x6f, 0x61, 0x6c, 0x20, 0x6f, 0x66, 0x20,
-  0x74, 0x68, 0x65, 0x20, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20,
-  0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x70, 0x72, 0x6f,
-  0x6a, 0x65, 0x63, 0x74, 0x20, 0x69, 0x73, 0x0a, 0x74, 0x6f, 0x20, 0x70,
-  0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x61, 0x20, 0x66, 0x72, 0x61,
-  0x6d, 0x65, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x77, 0x68,
-  0x69, 0x63, 0x68, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79,
-  0x20, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65, 0x72,
-  0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65,
-  0x20, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x64, 0x2c, 0x20,
-  0x74, 0x65, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x65,
-  0x61, 0x73, 0x69, 0x6c, 0x79, 0x20, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79,
-  0x65, 0x64, 0x20, 0x74, 0x6f, 0x0a, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e,
-  0x20, 0x61, 0x6e, 0x79, 0x20, 0x6f, 0x66, 0x20, 0x74, 0x68, 0x65, 0x20,
-  0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x20, 0x65, 0x6e,
-  0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2e, 0x20,
-  0x41, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x20, 0x73, 0x65, 0x74, 0x20, 0x6f,
-  0x66, 0x20, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x73, 0x65,
-  0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x69,
-  0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x65, 0x64, 0x20, 0x74,
-  0x6f, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x62, 0x61,
-  0x73, 0x69, 0x63, 0x0a, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x73,
-  0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x20, 0x66, 0x75, 0x6e, 0x63,
-  0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x73, 0x75, 0x63, 0x68, 0x20, 0x61,
-  0x73, 0x20, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x67, 0x72, 0x61, 0x70,
-  0x68, 0x79, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72,
-  0x65, 0x20, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x0a, 0x0a,
-  0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x69, 0x73, 0x6f, 0x6c,
-  0x61, 0x74, 0x65, 0x64, 0x20, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73,
-  0x69, 0x6e, 0x67, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d,
-  0x65, 0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x3a, 0x0a, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x53, 0x65, 0x63, 0x75, 0x72,
+  0x6e, 0x74, 0x73, 0x20, 0x61, 0x72, 0x65, 0x3a, 0x0a, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65,
+  0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2a,
+  0x2a, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x77,
+  0x6f, 0x72, 0x6c, 0x64, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74, 0x65,
+  0x64, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e,
+  0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x20, 0x62,
+  0x79, 0x20, 0x61, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x70,
+  0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61, 0x6e,
+  0x61, 0x67, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x2a,
+  0x2a, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61, 0x70, 0x70,
+  0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2a, 0x2a, 0x20,
+  0x2d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+  0x6e, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e,
+  0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x20, 0x62,
+  0x79, 0x20, 0x61, 0x20, 0x54, 0x45, 0x45, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x2d, 0x20, 0x2a, 0x2a, 0x56, 0x4d, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x65,
+  0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2a,
+  0x2a, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
+  0x72, 0x20, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x74, 0x68,
+  0x61, 0x74, 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20, 0x68, 0x79,
+  0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x20, 0x74, 0x6f, 0x20,
+  0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x68, 0x61, 0x72, 0x64,
+  0x77, 0x61, 0x72, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x64, 0x20,
+  0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x69, 0x73,
+  0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x0a, 0x54, 0x68, 0x65,
+  0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x72, 0x65, 0x66,
+  0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74, 0x65,
+  0x6d, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72, 0x20,
+  0x74, 0x65, 0x73, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x65, 0x76,
+  0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x75, 0x73,
+  0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
+  0x65, 0x20, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20,
+  0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e, 0x66,
+  0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6f, 0x66,
+  0x20, 0x4f, 0x50, 0x2d, 0x54, 0x45, 0x45, 0x20, 0x74, 0x6f, 0x20, 0x6d,
+  0x61, 0x6e, 0x61, 0x67, 0x65, 0x20, 0x61, 0x20, 0x73, 0x65, 0x74, 0x20,
+  0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x70, 0x61,
+  0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72, 0x75, 0x6e,
+  0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74, 0x20, 0x53, 0x2d, 0x45, 0x4c,
+  0x30, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72,
   0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73,
-  0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
-  0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x69, 0x73, 0x6f, 0x6c, 0x61, 0x74,
-  0x65, 0x64, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65,
-  0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x20,
-  0x62, 0x79, 0x20, 0x61, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20,
-  0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x6d, 0x61,
-  0x6e, 0x61, 0x67, 0x65, 0x72, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20,
-  0x2a, 0x2a, 0x54, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x61, 0x70,
-  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2a, 0x2a,
-  0x20, 0x2d, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
-  0x6f, 0x6e, 0x20, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65,
-  0x6e, 0x74, 0x73, 0x20, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x20,
-  0x62, 0x79, 0x20, 0x61, 0x20, 0x54, 0x45, 0x45, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x2d, 0x20, 0x2a, 0x2a, 0x56, 0x4d, 0x20, 0x62, 0x61, 0x63, 0x6b,
-  0x65, 0x64, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
-  0x2a, 0x2a, 0x20, 0x2d, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
-  0x65, 0x72, 0x20, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x20, 0x74,
-  0x68, 0x61, 0x74, 0x20, 0x75, 0x73, 0x65, 0x73, 0x20, 0x61, 0x20, 0x68,
-  0x79, 0x70, 0x65, 0x72, 0x76, 0x69, 0x73, 0x6f, 0x72, 0x20, 0x74, 0x6f,
-  0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x68, 0x61, 0x72,
-  0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x64,
-  0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x69,
-  0x73, 0x6f, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x0a, 0x54, 0x68,
-  0x65, 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x20, 0x72, 0x65,
-  0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x20, 0x73, 0x79, 0x73, 0x74,
-  0x65, 0x6d, 0x2c, 0x20, 0x75, 0x73, 0x65, 0x64, 0x20, 0x66, 0x6f, 0x72,
-  0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x64, 0x65,
-  0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x75,
-  0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x65, 0x63, 0x75,
-  0x72, 0x65, 0x20, 0x50, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
-  0x20, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x20, 0x63, 0x6f, 0x6e,
-  0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x0a, 0x6f,
-  0x66, 0x20, 0x4f, 0x50, 0x2d, 0x54, 0x45, 0x45, 0x20, 0x74, 0x6f, 0x20,
-  0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x20, 0x61, 0x20, 0x73, 0x65, 0x74,
-  0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x70,
-  0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x72, 0x75,
-  0x6e, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x61, 0x74, 0x20, 0x53, 0x2d, 0x45,
-  0x4c, 0x30, 0x2e, 0x20, 0x54, 0x68, 0x65, 0x20, 0x73, 0x65, 0x63, 0x75,
-  0x72, 0x65, 0x20, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e,
-  0x73, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69,
-  0x63, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73,
-  0x0a, 0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d,
-  0x65, 0x6e, 0x74, 0x20, 0x50, 0x53, 0x41, 0x20, 0x72, 0x6f, 0x6f, 0x74,
-  0x2d, 0x6f, 0x66, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x73, 0x65,
-  0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x53, 0x65, 0x72, 0x76,
-  0x69, 0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20,
-  0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x75, 0x73, 0x69,
-  0x6e, 0x67, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x69,
-  0x64, 0x65, 0x20, 0x43, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67,
-  0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73,
-  0x65, 0x20, 0x50, 0x53, 0x41, 0x0a, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69,
-  0x6f, 0x6e, 0x61, 0x6c, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, 0x55,
-  0x45, 0x46, 0x49, 0x20, 0x53, 0x4d, 0x4d, 0x20, 0x73, 0x65, 0x72, 0x76,
-  0x69, 0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f,
-  0x76, 0x69, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65,
-  0x20, 0x53, 0x4d, 0x4d, 0x20, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79,
-  0x2e, 0x0a
+  0x20, 0x68, 0x6f, 0x73, 0x74, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
+  0x65, 0x20, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x73, 0x0a,
+  0x74, 0x68, 0x61, 0x74, 0x20, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65,
+  0x6e, 0x74, 0x20, 0x50, 0x53, 0x41, 0x20, 0x72, 0x6f, 0x6f, 0x74, 0x2d,
+  0x6f, 0x66, 0x2d, 0x74, 0x72, 0x75, 0x73, 0x74, 0x20, 0x73, 0x65, 0x72,
+  0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x20, 0x53, 0x65, 0x72, 0x76, 0x69,
+  0x63, 0x65, 0x73, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x62, 0x65, 0x20, 0x61,
+  0x63, 0x63, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x75, 0x73, 0x69, 0x6e,
+  0x67, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x64,
+  0x65, 0x20, 0x43, 0x20, 0x62, 0x69, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x73,
+  0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x65, 0x78, 0x70, 0x6f, 0x73, 0x65,
+  0x20, 0x50, 0x53, 0x41, 0x0a, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
+  0x6e, 0x61, 0x6c, 0x20, 0x41, 0x50, 0x49, 0x73, 0x2e, 0x20, 0x55, 0x45,
+  0x46, 0x49, 0x20, 0x53, 0x4d, 0x4d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69,
+  0x63, 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x70, 0x72, 0x6f, 0x76,
+  0x69, 0x64, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20,
+  0x53, 0x4d, 0x4d, 0x20, 0x47, 0x61, 0x74, 0x65, 0x77, 0x61, 0x79, 0x2e,
+  0x0a
 };
-unsigned int var_data_txt_len = 2030;
+unsigned int var_data_txt_len = 2029;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/var_delete.h b/components/service/uefi/smm_variable/test/service/auth_vectors/var_delete.h
index e4b82b5..f5df0c9 100644
--- a/components/service/uefi/smm_variable/test/service/auth_vectors/var_delete.h
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/var_delete.h
@@ -7,108 +7,106 @@
  */
 
 unsigned char VAR_delete_auth[] = {
-  0xe8, 0x07, 0x01, 0x1a, 0x11, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0xb9, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0xe8, 0x07, 0x06, 0x0b, 0x0c, 0x16, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
   0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
-  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x9d, 0x06, 0x09, 0x2a, 0x86,
-  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x04, 0x8e, 0x30,
-  0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x09,
-  0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30,
-  0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01,
-  0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03, 0x07, 0x30, 0x82, 0x01, 0xef,
-  0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x2d, 0x56, 0x6b, 0xbb, 0xa5,
-  0x07, 0xa3, 0xa2, 0x44, 0x17, 0xca, 0x1c, 0xe2, 0xfc, 0xd3, 0x2e, 0x3c,
-  0x6b, 0x4b, 0x65, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20,
-  0x44, 0x42, 0x31, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x31, 0x32,
-  0x36, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x17, 0x0d, 0x33, 0x34,
-  0x30, 0x31, 0x32, 0x33, 0x31, 0x36, 0x32, 0x30, 0x30, 0x38, 0x5a, 0x30,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x44, 0x88, 0xdb, 0x5e, 0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe,
+  0x7d, 0x2c, 0xa2, 0xf6, 0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
   0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
-  0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42, 0x31, 0x30, 0x82, 0x01, 0x22,
-  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
-  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
-  0x02, 0x82, 0x01, 0x01, 0x00, 0xac, 0x13, 0xa9, 0xbb, 0x26, 0x22, 0x4c,
-  0x0f, 0xa9, 0x0a, 0x55, 0xbb, 0x40, 0x66, 0x73, 0xb2, 0x9f, 0x0e, 0x3a,
-  0xe8, 0x08, 0xce, 0xcd, 0x0d, 0x2b, 0xd9, 0xd1, 0x7e, 0x0b, 0x37, 0x6a,
-  0xf7, 0x7b, 0xb0, 0x21, 0x24, 0x61, 0x1d, 0xbb, 0x34, 0xb6, 0x28, 0x7b,
-  0xae, 0x77, 0x5b, 0x78, 0xab, 0x27, 0x5d, 0x65, 0xea, 0xe2, 0x8b, 0x89,
-  0x05, 0x2c, 0x61, 0xe6, 0x4d, 0x7b, 0x9f, 0xbc, 0xaa, 0x21, 0xff, 0x50,
-  0x86, 0x17, 0x7d, 0x41, 0x48, 0x80, 0xea, 0x60, 0x2c, 0xe9, 0x66, 0x20,
-  0x78, 0x84, 0xb6, 0x20, 0x1b, 0x47, 0xbd, 0x71, 0x26, 0x77, 0x4d, 0x41,
-  0x97, 0x65, 0x6b, 0x08, 0xcb, 0x68, 0xb5, 0xab, 0x73, 0x4a, 0xb8, 0x11,
-  0x60, 0x16, 0x3b, 0xc7, 0x34, 0x22, 0x01, 0xf7, 0x65, 0xbf, 0xf5, 0x8e,
-  0x3b, 0x93, 0xc4, 0x9f, 0xf5, 0xe8, 0xc2, 0x1f, 0xf9, 0x9d, 0xce, 0xf5,
-  0xa1, 0xe6, 0x60, 0x3c, 0xa6, 0xa7, 0xb6, 0xe3, 0xea, 0xc1, 0x18, 0x92,
-  0xde, 0x01, 0xe5, 0xbd, 0xf9, 0x9a, 0x8c, 0x39, 0x54, 0x67, 0x73, 0x57,
-  0xaa, 0x26, 0xce, 0x6f, 0x01, 0x7c, 0x29, 0xc1, 0xba, 0xf6, 0xad, 0x5f,
-  0x55, 0x12, 0x54, 0x65, 0xcd, 0xe6, 0xe5, 0x13, 0x4f, 0xf3, 0xc1, 0xed,
-  0xba, 0x1f, 0x32, 0x1a, 0x41, 0x02, 0xfe, 0x2b, 0x41, 0x07, 0xce, 0xc1,
-  0x69, 0x91, 0x93, 0xc8, 0x3d, 0x6d, 0x7c, 0xa8, 0xc8, 0xcb, 0xaa, 0x39,
-  0xf6, 0x59, 0x6f, 0x40, 0x48, 0xef, 0x16, 0xf7, 0xf3, 0xdf, 0xd5, 0xc2,
-  0x1a, 0xa6, 0xed, 0xff, 0x05, 0xa5, 0xac, 0x39, 0x32, 0x18, 0xcb, 0xe1,
-  0x87, 0x0f, 0xf8, 0x04, 0x55, 0x50, 0xb7, 0xfb, 0xa2, 0xa2, 0x05, 0x33,
-  0xa5, 0x15, 0x46, 0xd8, 0x14, 0x35, 0xd2, 0x08, 0x14, 0x48, 0x15, 0x45,
-  0x0a, 0x7d, 0xfd, 0xa5, 0x36, 0x7e, 0xd4, 0x23, 0xb9, 0x02, 0x03, 0x01,
-  0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
-  0x0e, 0x04, 0x16, 0x04, 0x14, 0x28, 0x8e, 0x10, 0x73, 0x79, 0x18, 0xac,
-  0xe1, 0xfc, 0xd1, 0x85, 0x96, 0x35, 0x62, 0xc3, 0x6c, 0xff, 0x30, 0x20,
-  0xcc, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
-  0x80, 0x14, 0x28, 0x8e, 0x10, 0x73, 0x79, 0x18, 0xac, 0xe1, 0xfc, 0xd1,
-  0x85, 0x96, 0x35, 0x62, 0xc3, 0x6c, 0xff, 0x30, 0x20, 0xcc, 0x30, 0x0f,
-  0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03,
-  0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
-  0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x4a,
-  0x19, 0x4b, 0x7a, 0xe2, 0x4c, 0xbb, 0x7a, 0xde, 0x38, 0xc0, 0xd2, 0x45,
-  0x8a, 0x18, 0x9e, 0x80, 0xfa, 0xfb, 0xed, 0x97, 0x0d, 0x29, 0x7a, 0xf3,
-  0x52, 0xc4, 0xc5, 0xfa, 0x57, 0x0b, 0x63, 0xf5, 0x7b, 0x45, 0x11, 0x7c,
-  0xed, 0x3e, 0xa1, 0x40, 0xd3, 0xef, 0x51, 0xb8, 0x18, 0x31, 0xba, 0xa4,
-  0x7f, 0x1f, 0x95, 0x3b, 0xd4, 0xae, 0x89, 0x47, 0xf2, 0x40, 0xa3, 0x04,
-  0x20, 0x31, 0x55, 0xb7, 0xf7, 0xcd, 0x05, 0x2b, 0x2c, 0xca, 0x55, 0xa6,
-  0xed, 0x0e, 0x84, 0x43, 0xfb, 0xcd, 0x22, 0xeb, 0xb9, 0x1e, 0xd4, 0x36,
-  0x49, 0x14, 0xcf, 0xa6, 0x75, 0x53, 0x1a, 0x9b, 0x64, 0x05, 0x18, 0x23,
-  0xa4, 0x4e, 0xb1, 0x95, 0x24, 0x07, 0xce, 0xca, 0x79, 0x57, 0x3a, 0x7f,
-  0xd6, 0x02, 0x3e, 0xf7, 0x7a, 0xde, 0x68, 0xd1, 0x5c, 0xc0, 0xbd, 0x60,
-  0xed, 0x56, 0xf5, 0x9f, 0xa1, 0x94, 0x68, 0x39, 0xa6, 0x9b, 0x9d, 0xdf,
-  0x98, 0x4a, 0x34, 0x39, 0xcc, 0xd5, 0x38, 0xc8, 0x2e, 0x66, 0x69, 0xaf,
-  0x6d, 0x46, 0xc8, 0x52, 0xc4, 0x9e, 0x9f, 0xe6, 0x4f, 0xa9, 0xd2, 0xf5,
-  0x15, 0x9a, 0xa1, 0xaa, 0xab, 0x09, 0x67, 0x76, 0x62, 0x6c, 0x5c, 0xf8,
-  0x1b, 0x4c, 0x57, 0x77, 0x53, 0x2c, 0xe0, 0x91, 0x8b, 0x63, 0xd3, 0xd0,
-  0xd4, 0xad, 0x89, 0x6c, 0x3d, 0xe2, 0x9a, 0xe2, 0x75, 0xf5, 0x33, 0xd3,
-  0x74, 0x1e, 0xd6, 0xd0, 0x5c, 0x41, 0x3e, 0xa2, 0x14, 0x04, 0x90, 0xde,
-  0xfd, 0x68, 0x5d, 0xbd, 0x87, 0x4f, 0x6c, 0x00, 0xae, 0x94, 0xa4, 0xf0,
-  0x8b, 0xb4, 0x29, 0x58, 0xd8, 0xd0, 0x9c, 0xa6, 0xd3, 0x62, 0x47, 0xee,
-  0x8c, 0xf6, 0xeb, 0xe9, 0x99, 0x86, 0x45, 0x55, 0xd7, 0x91, 0xc9, 0xe6,
-  0xcb, 0x2e, 0xa2, 0x63, 0x16, 0xc9, 0x30, 0xdf, 0x72, 0x59, 0x06, 0xe8,
-  0x22, 0x6b, 0xda, 0x31, 0x82, 0x01, 0x56, 0x30, 0x82, 0x01, 0x52, 0x02,
-  0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
-  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x44, 0x42,
-  0x31, 0x02, 0x14, 0x2d, 0x56, 0x6b, 0xbb, 0xa5, 0x07, 0xa3, 0xa2, 0x44,
-  0x17, 0xca, 0x1c, 0xe2, 0xfc, 0xd3, 0x2e, 0x3c, 0x6b, 0x4b, 0x65, 0x30,
-  0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
-  0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
-  0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x59, 0x08, 0x5e,
-  0x9c, 0xd8, 0x49, 0xdc, 0x09, 0xb9, 0x67, 0x8c, 0x2d, 0x60, 0x2b, 0x66,
-  0x01, 0x29, 0x88, 0x50, 0x44, 0x3d, 0xc5, 0x03, 0xab, 0x2d, 0x86, 0xe6,
-  0x2e, 0xd8, 0x0b, 0x94, 0x10, 0xfd, 0x26, 0x38, 0x9e, 0xe4, 0xf7, 0xfc,
-  0x91, 0x89, 0x95, 0x63, 0x54, 0x99, 0x99, 0xd2, 0xae, 0x66, 0x3a, 0xb2,
-  0x81, 0x25, 0x94, 0xc9, 0x85, 0x9a, 0x53, 0xf8, 0x37, 0xd3, 0x2b, 0xc3,
-  0xb7, 0xcf, 0x80, 0x67, 0x8f, 0x04, 0x01, 0x1a, 0xd0, 0x26, 0x8e, 0x3f,
-  0x01, 0x1c, 0x5d, 0x4c, 0xc8, 0x15, 0x32, 0x54, 0xc1, 0x35, 0x09, 0x90,
-  0x60, 0x77, 0xcb, 0xe7, 0x93, 0x1e, 0x50, 0x2f, 0x62, 0x71, 0x3a, 0x0f,
-  0x7f, 0xc5, 0x69, 0xe1, 0xf1, 0x5a, 0x42, 0xcf, 0xad, 0x92, 0x57, 0x2a,
-  0x99, 0x3b, 0xd6, 0xf6, 0x16, 0x21, 0xed, 0x09, 0xa2, 0x53, 0x24, 0xcf,
-  0x79, 0x91, 0x75, 0x3f, 0x63, 0x32, 0x2f, 0xf1, 0xcb, 0xaf, 0x4e, 0x45,
-  0xb6, 0xc2, 0xb8, 0xc3, 0x48, 0xcf, 0x5c, 0xae, 0x36, 0xdb, 0xc7, 0x6d,
-  0x55, 0xe2, 0x79, 0x3f, 0x0b, 0xb7, 0x7d, 0x9e, 0x11, 0x5c, 0x71, 0xb6,
-  0xd6, 0x78, 0xe7, 0x75, 0xcd, 0x2b, 0x42, 0x5c, 0xd9, 0x91, 0x17, 0x9b,
-  0xc7, 0x1a, 0xe3, 0xf2, 0x9e, 0x4f, 0x84, 0x68, 0xf9, 0xa4, 0xd2, 0xc4,
-  0xcd, 0x2e, 0xa9, 0x35, 0x8c, 0x75, 0xb1, 0xcb, 0xb7, 0x2c, 0x4d, 0xfe,
-  0xa1, 0x7f, 0xaf, 0x62, 0xf0, 0x26, 0x98, 0x33, 0x05, 0x94, 0x09, 0xbb,
-  0x94, 0xd6, 0x5e, 0x24, 0xbf, 0xff, 0x4e, 0x9a, 0x32, 0xf8, 0xa4, 0x17,
-  0x43, 0xb4, 0x9b, 0x50, 0xa2, 0x83, 0x7a, 0x83, 0x97, 0x8d, 0x43, 0x09,
-  0x36, 0x3c, 0xa1, 0x7d, 0x3d, 0xd0, 0x56, 0x34, 0xe3, 0x00, 0xf6, 0x37,
-  0x76, 0x13, 0x38, 0xec, 0xc4, 0xb4, 0xaa, 0x59, 0xfa, 0xd6, 0xbc, 0xcd,
-  0xa6
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x35, 0x30,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x35, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41,
+  0x52, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd8, 0x81,
+  0xc4, 0x49, 0x3c, 0xe5, 0x73, 0xf5, 0x26, 0x5d, 0x90, 0x9e, 0xae, 0x06,
+  0x7f, 0x8a, 0x38, 0xd6, 0x51, 0xe5, 0xf5, 0xb9, 0x2e, 0xe9, 0x52, 0x00,
+  0x9b, 0x8a, 0x19, 0xf8, 0xcb, 0xa9, 0xb0, 0xb9, 0x7f, 0xae, 0xff, 0x03,
+  0x5d, 0xf2, 0x36, 0xa3, 0xfd, 0x58, 0x21, 0xc3, 0x10, 0x50, 0xfe, 0xff,
+  0x85, 0xbd, 0x79, 0x73, 0x8a, 0xb1, 0xa9, 0x1a, 0x87, 0x53, 0x7d, 0xd4,
+  0x3c, 0x46, 0x0e, 0x9a, 0x38, 0xca, 0xb0, 0x4e, 0xcd, 0xf6, 0x16, 0x60,
+  0x7c, 0xa0, 0x30, 0xc6, 0x1f, 0x41, 0xbe, 0x10, 0x54, 0x65, 0x27, 0xd3,
+  0x5c, 0x57, 0x6f, 0x60, 0xf6, 0x53, 0x1a, 0x17, 0xae, 0xdb, 0x17, 0xc6,
+  0x8f, 0x9d, 0xdc, 0x5f, 0xdc, 0xf0, 0x23, 0xba, 0xf1, 0xf0, 0xf8, 0x7d,
+  0xb6, 0x44, 0xa8, 0x9b, 0xf6, 0x61, 0xd7, 0xa5, 0x38, 0xd8, 0x71, 0xcb,
+  0x13, 0xe0, 0xd1, 0x35, 0x99, 0x1a, 0xbd, 0x4d, 0x89, 0x4b, 0x40, 0xa0,
+  0xca, 0xf4, 0x84, 0x01, 0xa7, 0xcc, 0xcd, 0xd0, 0xb7, 0xef, 0xb5, 0x9f,
+  0x48, 0x57, 0x19, 0x40, 0x6e, 0x5b, 0x51, 0x7c, 0xf5, 0x70, 0x48, 0x3b,
+  0xf9, 0x94, 0x5f, 0xc4, 0xc9, 0xce, 0x5a, 0xf7, 0x56, 0x3b, 0xa7, 0xa6,
+  0x0e, 0x73, 0x99, 0x7f, 0x97, 0x92, 0x40, 0x0d, 0x82, 0x50, 0x41, 0xf2,
+  0x8d, 0xe6, 0x0b, 0xa0, 0xfe, 0x1e, 0xfc, 0x66, 0xa5, 0x5c, 0x5c, 0xc2,
+  0xee, 0x4c, 0x41, 0x9e, 0xfc, 0xa1, 0x9c, 0xf3, 0xf6, 0xb7, 0xce, 0xaf,
+  0x3c, 0xb4, 0x32, 0x71, 0x2c, 0x0c, 0x5d, 0x69, 0x33, 0xbe, 0xca, 0xe9,
+  0x4d, 0x08, 0x14, 0xe9, 0x37, 0x48, 0x84, 0xda, 0x97, 0xd7, 0xec, 0xa2,
+  0xc3, 0x54, 0x66, 0x6a, 0x87, 0x28, 0xdd, 0x8d, 0x23, 0x47, 0x75, 0x0a,
+  0x76, 0x7e, 0xed, 0x72, 0x18, 0x20, 0xbf, 0xd4, 0x1b, 0xc7, 0x88, 0xd9,
+  0x74, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, 0x9d,
+  0xc8, 0x8c, 0x3c, 0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26,
+  0xb9, 0x80, 0x4b, 0xf2, 0x3b, 0x23, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x9d, 0xc8, 0x8c, 0x3c,
+  0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26, 0xb9, 0x80, 0x4b,
+  0xf2, 0x3b, 0x23, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x94, 0x47, 0x24, 0x8b, 0xfe, 0x3e, 0x28, 0xb1,
+  0x88, 0xed, 0x6c, 0x7f, 0x65, 0x48, 0xa6, 0x15, 0x0c, 0x47, 0xba, 0x9c,
+  0x90, 0x67, 0xf7, 0x5d, 0x64, 0x76, 0x61, 0x17, 0x81, 0x7b, 0xe0, 0x25,
+  0x4b, 0xe4, 0xfe, 0x9e, 0x76, 0x70, 0xe2, 0x19, 0x57, 0x22, 0x4e, 0x1e,
+  0x07, 0xc1, 0x4a, 0xc7, 0xe1, 0xc8, 0x57, 0xc9, 0x06, 0xe1, 0x6e, 0x8e,
+  0x12, 0xd7, 0xe5, 0x94, 0xc7, 0xa1, 0xdf, 0xcb, 0xcd, 0xe1, 0xac, 0x5c,
+  0xcf, 0x96, 0xf9, 0x1d, 0xdd, 0xb4, 0x02, 0x20, 0xdd, 0xa8, 0xc6, 0xae,
+  0x72, 0xd9, 0x2e, 0xc8, 0xe1, 0x07, 0x8d, 0xd4, 0x63, 0x00, 0x59, 0x26,
+  0x8d, 0x73, 0x36, 0x23, 0x36, 0xd4, 0x38, 0x42, 0xc2, 0x0a, 0xef, 0x68,
+  0x3e, 0x26, 0xff, 0x12, 0xaf, 0x5b, 0xf0, 0xa0, 0x8e, 0xb7, 0xce, 0xc1,
+  0x88, 0xc3, 0x9f, 0x50, 0x77, 0xa4, 0x44, 0x33, 0x9a, 0x44, 0x8e, 0x1b,
+  0x83, 0x80, 0xd4, 0xc9, 0xa6, 0x81, 0xfe, 0x87, 0x1f, 0x77, 0x04, 0x7f,
+  0x0f, 0xb4, 0x5e, 0x88, 0x40, 0x70, 0xd4, 0x3d, 0xeb, 0x96, 0xba, 0x15,
+  0xa8, 0x7a, 0x5a, 0x26, 0x6a, 0x36, 0xe4, 0x6b, 0x87, 0x11, 0x11, 0xc2,
+  0x3b, 0xa5, 0x50, 0x10, 0x5d, 0x3f, 0x00, 0xf4, 0x62, 0x37, 0x93, 0xee,
+  0x4b, 0x13, 0x38, 0xf5, 0xc7, 0x17, 0xef, 0x7f, 0xda, 0x10, 0x76, 0x9c,
+  0xc9, 0x2c, 0x11, 0xb4, 0xc2, 0x21, 0x8e, 0x72, 0x50, 0x9e, 0xf7, 0x98,
+  0x3c, 0x8e, 0xee, 0xa1, 0xd9, 0xf8, 0x46, 0x17, 0x89, 0x38, 0xaf, 0x59,
+  0xdb, 0x03, 0xd0, 0x50, 0x9e, 0x97, 0x1b, 0xf6, 0x7a, 0x15, 0x61, 0x24,
+  0xef, 0xa3, 0x9a, 0x7a, 0x0f, 0x05, 0x54, 0x22, 0x26, 0x93, 0x3d, 0xd7,
+  0x3b, 0x04, 0x1e, 0xe3, 0x13, 0xb7, 0xb0, 0xb1, 0x98, 0x8a, 0x6d, 0xfb,
+  0x11, 0x5e, 0x37, 0x29, 0x37, 0x54, 0x78, 0x42, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x02, 0x14, 0x44, 0x88, 0xdb, 0x5e,
+  0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe, 0x7d, 0x2c, 0xa2, 0xf6,
+  0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x60, 0x01, 0x14, 0x9d, 0xa4, 0x81, 0xd5, 0x1f, 0x93, 0xf9,
+  0x5a, 0xcc, 0xb1, 0xcd, 0xf3, 0xe4, 0x2b, 0xef, 0x38, 0x7c, 0x3f, 0xd1,
+  0xe2, 0x85, 0xdf, 0x36, 0xd9, 0x2a, 0xa9, 0xe6, 0x6a, 0x94, 0x76, 0x49,
+  0x61, 0x86, 0xac, 0x33, 0x7b, 0xc1, 0x1b, 0xaf, 0xe3, 0xa4, 0x35, 0x32,
+  0xd6, 0x9d, 0x1c, 0xbc, 0xe8, 0x0f, 0x95, 0xaf, 0xbc, 0xc6, 0x54, 0xeb,
+  0xd2, 0x40, 0x8a, 0x46, 0xb6, 0x39, 0x68, 0x25, 0x8f, 0xce, 0x06, 0xbc,
+  0x81, 0x89, 0x70, 0x76, 0x7e, 0x5f, 0xa0, 0xa6, 0x9f, 0x6c, 0xc0, 0xe4,
+  0x61, 0x2f, 0x42, 0xa1, 0xed, 0xbd, 0x8a, 0x26, 0x43, 0xc2, 0x23, 0xb5,
+  0x13, 0x2a, 0xd3, 0xd6, 0xe2, 0x67, 0x0c, 0x22, 0xf4, 0xda, 0x2f, 0x46,
+  0x75, 0x73, 0x43, 0x6f, 0x62, 0x54, 0xc6, 0x16, 0x30, 0x83, 0x99, 0xe4,
+  0xc1, 0xd4, 0x5b, 0x16, 0x45, 0x54, 0xbe, 0x59, 0xa8, 0x76, 0x3b, 0x1d,
+  0x72, 0x9d, 0x02, 0xa5, 0x7f, 0x2c, 0xc0, 0x1b, 0x91, 0x66, 0xaa, 0x81,
+  0xb2, 0x08, 0x1b, 0x7d, 0x58, 0x29, 0x1e, 0x23, 0x20, 0x64, 0x33, 0x83,
+  0x2f, 0x8a, 0x21, 0x2d, 0x44, 0x8b, 0xfb, 0x64, 0x6d, 0xd5, 0x7f, 0x5b,
+  0x9e, 0x9c, 0xbd, 0x5d, 0xa6, 0x0c, 0x32, 0x53, 0x82, 0x81, 0xc3, 0xe5,
+  0x37, 0xdb, 0xd0, 0xec, 0xe1, 0x74, 0xb7, 0x12, 0x7d, 0x21, 0xcb, 0xfa,
+  0xe1, 0x24, 0xe6, 0xd8, 0x4a, 0x2f, 0x9e, 0xba, 0x79, 0x76, 0x80, 0xb0,
+  0xae, 0x07, 0x8a, 0xc7, 0xd3, 0xf2, 0x81, 0x04, 0x98, 0xa9, 0x3b, 0xfd,
+  0x8b, 0x69, 0x40, 0xf9, 0x01, 0x02, 0x72, 0x97, 0x8d, 0xcf, 0x4d, 0xdc,
+  0x2a, 0x0b, 0xfc, 0x70, 0x42, 0x24, 0x3b, 0x55, 0xf5, 0xa5, 0x4f, 0xc9,
+  0xc5, 0x4c, 0xd3, 0xcf, 0x99, 0xa9, 0xf2, 0x6f, 0x30, 0xf0, 0xaa, 0x43,
+  0xbb, 0x40, 0xd1, 0x7b, 0xbe, 0xb5
 };
-unsigned int VAR_delete_auth_len = 1225;
+unsigned int VAR_delete_auth_len = 1206;
diff --git a/components/service/uefi/smm_variable/test/service/auth_vectors/var_delete_old.h b/components/service/uefi/smm_variable/test/service/auth_vectors/var_delete_old.h
new file mode 100644
index 0000000..d3eaf41
--- /dev/null
+++ b/components/service/uefi/smm_variable/test/service/auth_vectors/var_delete_old.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file was generated by generate_auth_headers.sh
+ */
+
+unsigned char VAR_delete_old_auth[] = {
+  0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0x02, 0xf1, 0x0e,
+  0x9d, 0xd2, 0xaf, 0x4a, 0xdf, 0x68, 0xee, 0x49, 0x8a, 0xa9, 0x34, 0x7d,
+  0x37, 0x56, 0x65, 0xa7, 0x30, 0x82, 0x04, 0x8a, 0x02, 0x01, 0x01, 0x31,
+  0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04,
+  0x02, 0x01, 0x05, 0x00, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
+  0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x03, 0x0b, 0x30, 0x82, 0x03,
+  0x07, 0x30, 0x82, 0x01, 0xef, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14,
+  0x44, 0x88, 0xdb, 0x5e, 0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe,
+  0x7d, 0x2c, 0xa2, 0xf6, 0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+  0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08,
+  0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x34, 0x30, 0x36, 0x31, 0x31, 0x31, 0x30, 0x32, 0x31, 0x35, 0x30,
+  0x5a, 0x17, 0x0d, 0x33, 0x34, 0x30, 0x36, 0x30, 0x39, 0x31, 0x30, 0x32,
+  0x31, 0x35, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03,
+  0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65, 0x73, 0x74, 0x20, 0x56, 0x41,
+  0x52, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+  0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd8, 0x81,
+  0xc4, 0x49, 0x3c, 0xe5, 0x73, 0xf5, 0x26, 0x5d, 0x90, 0x9e, 0xae, 0x06,
+  0x7f, 0x8a, 0x38, 0xd6, 0x51, 0xe5, 0xf5, 0xb9, 0x2e, 0xe9, 0x52, 0x00,
+  0x9b, 0x8a, 0x19, 0xf8, 0xcb, 0xa9, 0xb0, 0xb9, 0x7f, 0xae, 0xff, 0x03,
+  0x5d, 0xf2, 0x36, 0xa3, 0xfd, 0x58, 0x21, 0xc3, 0x10, 0x50, 0xfe, 0xff,
+  0x85, 0xbd, 0x79, 0x73, 0x8a, 0xb1, 0xa9, 0x1a, 0x87, 0x53, 0x7d, 0xd4,
+  0x3c, 0x46, 0x0e, 0x9a, 0x38, 0xca, 0xb0, 0x4e, 0xcd, 0xf6, 0x16, 0x60,
+  0x7c, 0xa0, 0x30, 0xc6, 0x1f, 0x41, 0xbe, 0x10, 0x54, 0x65, 0x27, 0xd3,
+  0x5c, 0x57, 0x6f, 0x60, 0xf6, 0x53, 0x1a, 0x17, 0xae, 0xdb, 0x17, 0xc6,
+  0x8f, 0x9d, 0xdc, 0x5f, 0xdc, 0xf0, 0x23, 0xba, 0xf1, 0xf0, 0xf8, 0x7d,
+  0xb6, 0x44, 0xa8, 0x9b, 0xf6, 0x61, 0xd7, 0xa5, 0x38, 0xd8, 0x71, 0xcb,
+  0x13, 0xe0, 0xd1, 0x35, 0x99, 0x1a, 0xbd, 0x4d, 0x89, 0x4b, 0x40, 0xa0,
+  0xca, 0xf4, 0x84, 0x01, 0xa7, 0xcc, 0xcd, 0xd0, 0xb7, 0xef, 0xb5, 0x9f,
+  0x48, 0x57, 0x19, 0x40, 0x6e, 0x5b, 0x51, 0x7c, 0xf5, 0x70, 0x48, 0x3b,
+  0xf9, 0x94, 0x5f, 0xc4, 0xc9, 0xce, 0x5a, 0xf7, 0x56, 0x3b, 0xa7, 0xa6,
+  0x0e, 0x73, 0x99, 0x7f, 0x97, 0x92, 0x40, 0x0d, 0x82, 0x50, 0x41, 0xf2,
+  0x8d, 0xe6, 0x0b, 0xa0, 0xfe, 0x1e, 0xfc, 0x66, 0xa5, 0x5c, 0x5c, 0xc2,
+  0xee, 0x4c, 0x41, 0x9e, 0xfc, 0xa1, 0x9c, 0xf3, 0xf6, 0xb7, 0xce, 0xaf,
+  0x3c, 0xb4, 0x32, 0x71, 0x2c, 0x0c, 0x5d, 0x69, 0x33, 0xbe, 0xca, 0xe9,
+  0x4d, 0x08, 0x14, 0xe9, 0x37, 0x48, 0x84, 0xda, 0x97, 0xd7, 0xec, 0xa2,
+  0xc3, 0x54, 0x66, 0x6a, 0x87, 0x28, 0xdd, 0x8d, 0x23, 0x47, 0x75, 0x0a,
+  0x76, 0x7e, 0xed, 0x72, 0x18, 0x20, 0xbf, 0xd4, 0x1b, 0xc7, 0x88, 0xd9,
+  0x74, 0x83, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, 0x9d,
+  0xc8, 0x8c, 0x3c, 0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26,
+  0xb9, 0x80, 0x4b, 0xf2, 0x3b, 0x23, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d,
+  0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x9d, 0x9d, 0xc8, 0x8c, 0x3c,
+  0x94, 0x29, 0x56, 0xe1, 0x4f, 0xe5, 0x56, 0x6d, 0x26, 0xb9, 0x80, 0x4b,
+  0xf2, 0x3b, 0x23, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01,
+  0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x01, 0x01, 0x00, 0x94, 0x47, 0x24, 0x8b, 0xfe, 0x3e, 0x28, 0xb1,
+  0x88, 0xed, 0x6c, 0x7f, 0x65, 0x48, 0xa6, 0x15, 0x0c, 0x47, 0xba, 0x9c,
+  0x90, 0x67, 0xf7, 0x5d, 0x64, 0x76, 0x61, 0x17, 0x81, 0x7b, 0xe0, 0x25,
+  0x4b, 0xe4, 0xfe, 0x9e, 0x76, 0x70, 0xe2, 0x19, 0x57, 0x22, 0x4e, 0x1e,
+  0x07, 0xc1, 0x4a, 0xc7, 0xe1, 0xc8, 0x57, 0xc9, 0x06, 0xe1, 0x6e, 0x8e,
+  0x12, 0xd7, 0xe5, 0x94, 0xc7, 0xa1, 0xdf, 0xcb, 0xcd, 0xe1, 0xac, 0x5c,
+  0xcf, 0x96, 0xf9, 0x1d, 0xdd, 0xb4, 0x02, 0x20, 0xdd, 0xa8, 0xc6, 0xae,
+  0x72, 0xd9, 0x2e, 0xc8, 0xe1, 0x07, 0x8d, 0xd4, 0x63, 0x00, 0x59, 0x26,
+  0x8d, 0x73, 0x36, 0x23, 0x36, 0xd4, 0x38, 0x42, 0xc2, 0x0a, 0xef, 0x68,
+  0x3e, 0x26, 0xff, 0x12, 0xaf, 0x5b, 0xf0, 0xa0, 0x8e, 0xb7, 0xce, 0xc1,
+  0x88, 0xc3, 0x9f, 0x50, 0x77, 0xa4, 0x44, 0x33, 0x9a, 0x44, 0x8e, 0x1b,
+  0x83, 0x80, 0xd4, 0xc9, 0xa6, 0x81, 0xfe, 0x87, 0x1f, 0x77, 0x04, 0x7f,
+  0x0f, 0xb4, 0x5e, 0x88, 0x40, 0x70, 0xd4, 0x3d, 0xeb, 0x96, 0xba, 0x15,
+  0xa8, 0x7a, 0x5a, 0x26, 0x6a, 0x36, 0xe4, 0x6b, 0x87, 0x11, 0x11, 0xc2,
+  0x3b, 0xa5, 0x50, 0x10, 0x5d, 0x3f, 0x00, 0xf4, 0x62, 0x37, 0x93, 0xee,
+  0x4b, 0x13, 0x38, 0xf5, 0xc7, 0x17, 0xef, 0x7f, 0xda, 0x10, 0x76, 0x9c,
+  0xc9, 0x2c, 0x11, 0xb4, 0xc2, 0x21, 0x8e, 0x72, 0x50, 0x9e, 0xf7, 0x98,
+  0x3c, 0x8e, 0xee, 0xa1, 0xd9, 0xf8, 0x46, 0x17, 0x89, 0x38, 0xaf, 0x59,
+  0xdb, 0x03, 0xd0, 0x50, 0x9e, 0x97, 0x1b, 0xf6, 0x7a, 0x15, 0x61, 0x24,
+  0xef, 0xa3, 0x9a, 0x7a, 0x0f, 0x05, 0x54, 0x22, 0x26, 0x93, 0x3d, 0xd7,
+  0x3b, 0x04, 0x1e, 0xe3, 0x13, 0xb7, 0xb0, 0xb1, 0x98, 0x8a, 0x6d, 0xfb,
+  0x11, 0x5e, 0x37, 0x29, 0x37, 0x54, 0x78, 0x42, 0x31, 0x82, 0x01, 0x56,
+  0x30, 0x82, 0x01, 0x52, 0x02, 0x01, 0x01, 0x30, 0x2b, 0x30, 0x13, 0x31,
+  0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x54, 0x65,
+  0x73, 0x74, 0x20, 0x56, 0x41, 0x52, 0x02, 0x14, 0x44, 0x88, 0xdb, 0x5e,
+  0x02, 0x60, 0x48, 0xbc, 0x39, 0x5f, 0xd7, 0xfe, 0x7d, 0x2c, 0xa2, 0xf6,
+  0x22, 0xbb, 0x7b, 0x65, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+  0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
+  0x01, 0x00, 0x7d, 0x00, 0x28, 0x99, 0xae, 0x59, 0xbb, 0x6a, 0x44, 0x0f,
+  0x1f, 0x51, 0x16, 0x78, 0x16, 0x86, 0x0c, 0xb6, 0x2f, 0x42, 0xb9, 0x8a,
+  0x64, 0x20, 0x90, 0x7a, 0x24, 0xb4, 0x73, 0xf7, 0xab, 0x79, 0x6e, 0xa4,
+  0x4e, 0xbd, 0xa6, 0x3e, 0xf6, 0x36, 0x31, 0x68, 0x87, 0xf1, 0xe2, 0x46,
+  0x51, 0x3b, 0x5e, 0xfa, 0xa4, 0x7d, 0x97, 0xc9, 0x9e, 0x6e, 0xac, 0x61,
+  0x4e, 0xe8, 0x57, 0x40, 0xbc, 0x97, 0x91, 0xab, 0x98, 0xfb, 0x2a, 0xcf,
+  0x91, 0xcc, 0x59, 0x26, 0xbf, 0x1c, 0x86, 0xc3, 0xaa, 0xf1, 0x92, 0x31,
+  0x22, 0xae, 0x98, 0x0d, 0xb9, 0x7d, 0x5d, 0x86, 0xb6, 0x8d, 0xce, 0x62,
+  0x41, 0x72, 0x6d, 0xfc, 0x7c, 0x25, 0x87, 0xb0, 0xf7, 0x27, 0x0e, 0x7b,
+  0x27, 0x08, 0xf2, 0x67, 0x97, 0xff, 0x63, 0x79, 0x0f, 0xad, 0x13, 0x0e,
+  0x4f, 0xa4, 0x0a, 0xd1, 0xd3, 0x9a, 0x6e, 0x9d, 0xb5, 0xa7, 0x20, 0x90,
+  0xf5, 0x93, 0x62, 0x97, 0x43, 0x02, 0xa3, 0x6b, 0x95, 0xa9, 0x22, 0x35,
+  0x72, 0xd3, 0xf0, 0x42, 0xa0, 0xc5, 0xea, 0x7c, 0xef, 0x2a, 0xd5, 0x32,
+  0x99, 0xfd, 0x00, 0x3f, 0x01, 0x87, 0x1c, 0x1a, 0x4d, 0x50, 0xfa, 0x5d,
+  0x18, 0xdd, 0xe0, 0x52, 0xeb, 0x3e, 0x0e, 0x25, 0x08, 0x90, 0xe8, 0x21,
+  0xff, 0xef, 0x95, 0x56, 0x5f, 0x63, 0x1c, 0xcf, 0x8a, 0xbd, 0xe4, 0x46,
+  0x96, 0x50, 0xe0, 0x5c, 0x61, 0xb5, 0xed, 0xe7, 0x79, 0xfc, 0x4d, 0x5a,
+  0x0e, 0xa2, 0xe9, 0x96, 0xbb, 0x43, 0xdc, 0x07, 0x30, 0xe3, 0xd8, 0x15,
+  0x65, 0xd4, 0xec, 0xc2, 0xb0, 0xb0, 0x5c, 0x6e, 0x2b, 0x23, 0x18, 0x72,
+  0xf1, 0x82, 0x25, 0xb7, 0x58, 0x95, 0x72, 0x66, 0xa8, 0x9d, 0x16, 0x76,
+  0x67, 0x94, 0x58, 0xfd, 0x10, 0x02, 0x93, 0xe8, 0x9f, 0x8c, 0x62, 0x9b,
+  0x28, 0x02, 0x30, 0xf5, 0xf7, 0x50
+};
+unsigned int VAR_delete_old_auth_len = 1206;
diff --git a/components/service/uefi/smm_variable/test/service/smm_variable_attack_tests.cpp b/components/service/uefi/smm_variable/test/service/smm_variable_attack_tests.cpp
index 76b62fd..98e61fe 100644
--- a/components/service/uefi/smm_variable/test/service/smm_variable_attack_tests.cpp
+++ b/components/service/uefi/smm_variable/test/service/smm_variable_attack_tests.cpp
@@ -176,19 +176,6 @@
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
 }
 
-TEST(SmmVariableAttackTests, enumerateWithOversizeName)
-{
-	efi_status_t efi_status = EFI_SUCCESS;
-	std::u16string var_name = null_name;
-	EFI_GUID guid;
-	memset(&guid, 0, sizeof(guid));
-
-	efi_status = m_client->get_next_variable_name(guid, var_name,
-						      (var_name.size() + 1) * sizeof(int16_t) + 1);
-
-	UNSIGNED_LONGLONGS_EQUAL(EFI_INVALID_PARAMETER, efi_status);
-}
-
 TEST(SmmVariableAttackTests, enumerateWithSizeMaxNameSize)
 {
 	efi_status_t efi_status = EFI_SUCCESS;
@@ -202,17 +189,23 @@
 
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
 
-	/* Initial iteration uses good name length */
-	efi_status = m_client->get_next_variable_name(guid, var_name);
+	/* Initial iteration uses good name length for next variable */
+	efi_status = m_client->get_next_variable_name(guid, var_name, std::numeric_limits<size_t>::max());
 
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
 
-	/* Next iteration uses invalid name length */
-	efi_status = m_client->get_next_variable_name(guid, var_name,
-						      std::numeric_limits<size_t>::max());
+	/* Next iteration uses invalid name length, so a null terminator can not fit */
+	var_name = null_name;
+	efi_status = m_client->get_next_variable_name(guid, var_name, 1);
 
 	UNSIGNED_LONGLONGS_EQUAL(EFI_INVALID_PARAMETER, efi_status);
 
+	/* Next iteration uses invalid name length, so a null terminator can not fit */
+	var_name = null_name;
+	efi_status = m_client->get_next_variable_name(guid, var_name, 2);
+
+	UNSIGNED_LONGLONGS_EQUAL(EFI_BUFFER_TOO_SMALL, efi_status);
+
 	/* Expect to be able to remove the variable */
 	efi_status = m_client->remove_variable(m_common_guid, var_name_1);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, efi_status);
diff --git a/components/service/uefi/smm_variable/test/service/smm_variable_service_tests.cpp b/components/service/uefi/smm_variable/test/service/smm_variable_service_tests.cpp
index e82a90c..7fcbb53 100644
--- a/components/service/uefi/smm_variable/test/service/smm_variable_service_tests.cpp
+++ b/components/service/uefi/smm_variable/test/service/smm_variable_service_tests.cpp
@@ -9,6 +9,7 @@
 #include <cstring>
 #include <locale>
 #include <sstream>
+#include <limits>
 
 #include "util.h"
 
@@ -23,8 +24,11 @@
 #include "auth_vectors/db1.h"
 #include "auth_vectors/db2.h"
 #include "auth_vectors/var.h"
+#include "auth_vectors/var_append.h"
+#include "auth_vectors/var_append_old.h"
 #include "auth_vectors/var_data.h"
 #include "auth_vectors/var_delete.h"
+#include "auth_vectors/var_delete_old.h"
 #endif
 #include "common/uuid/uuid.h"
 #include "protocols/rpc/common/packed-c/encoding.h"
@@ -154,7 +158,7 @@
 #endif
 
 		do {
-			status = m_client->get_next_variable_name(guid, var_name);
+			status = m_client->get_next_variable_name(guid, var_name, max_variable_size);
 
 			/* There are no more variables in the persistent store */
 			if (status == EFI_NOT_FOUND) {
@@ -223,6 +227,8 @@
 	std::u16string m_ro_variable = to_variable_name(u"ro_variable");
 	std::u16string m_boot_finished_var_name = to_variable_name(u"finished");
 
+	uint32_t max_variable_size = 4096;
+
 	/* Cleanup skips these variables */
 	std::vector<std::u16string *> m_non_rm_vars{ &m_ro_variable, &m_boot_finished_var_name };
 
@@ -244,8 +250,8 @@
 		EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS |
 		EFI_VARIABLE_BOOTSERVICE_ACCESS |
 		EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
-	uint8_t m_empty_auth_header[40] = { /* TimeStamp */
-					    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+	uint8_t m_empty_auth_header[40] = { /* TimeStamp in the far future */
+					    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0,
 					    /* dwLength = header size - sizeof (TimeStamp) */
 					    24, 0, 0, 0,
 					    /* wRevision = WIN_CERT_CURRENT_VERSION */
@@ -654,7 +660,7 @@
 	std::u16string *expected_variables[] = { &var_name_1, &var_name_2, &var_name_3 };
 
 	do {
-		efi_status = m_client->get_next_variable_name(guid, var_name);
+		efi_status = m_client->get_next_variable_name(guid, var_name, max_variable_size);
 		if (efi_status != EFI_SUCCESS)
 			break;
 
@@ -754,21 +760,76 @@
 }
 
 #if defined(UEFI_AUTH_VAR)
-TEST(SmmVariableServiceTests, authenticationDisabled)
+TEST(SmmVariableServiceTests, privAuthVarSetAndGet)
 {
 	efi_status_t status;
 	std::string read_data;
 
-	/* Without PK the authentication is disabled so each variable are writable, even in wrong order */
+	/* Set variable */
 	status = m_client->set_variable(m_common_guid, u"var", VAR_auth, sizeof(VAR_auth),
 					m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 
+	/* Overwrite variable with the same timestamp */
+	status = m_client->set_variable(m_common_guid, u"var", VAR_auth, sizeof(VAR_auth),
+					m_authentication_common_attributes);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SECURITY_VIOLATION, status);
+
+	/* Append variable with the same timestamp */
+	status = m_client->set_variable(m_common_guid, u"var", VAR_append_auth, sizeof(VAR_append_auth),
+					m_authentication_common_attributes | EFI_VARIABLE_APPEND_WRITE);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+	/* Get and validate variable value */
 	status = m_client->get_variable(m_common_guid, u"var", read_data);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 	UNSIGNED_LONGS_EQUAL(var_data_txt_len, read_data.size());
 	MEMCMP_EQUAL(var_data_txt, read_data.c_str(), var_data_txt_len);
 
+	/* Try deleting the variable with old timestamp */
+	status = m_client->set_variable(m_common_guid, u"var", VAR_delete_old_auth,
+					sizeof(VAR_delete_old_auth),
+					m_authentication_common_attributes);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SECURITY_VIOLATION, status);
+
+	/* Delete variable */
+	status = m_client->set_variable(m_common_guid, u"var", VAR_delete_auth,
+					sizeof(VAR_delete_auth),
+					m_authentication_common_attributes);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+	/* Check if it doesn't exist */
+	status = m_client->get_variable(m_common_guid, u"var", read_data);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
+
+	/* Set variable again */
+	status = m_client->set_variable(m_common_guid, u"var", VAR_auth, sizeof(VAR_auth),
+					m_authentication_common_attributes);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+	/* Append variable with the old timestamp which should not modify the timestamp */
+	status = m_client->set_variable(m_common_guid, u"var", VAR_append_old_auth, sizeof(VAR_append_old_auth),
+					m_authentication_common_attributes | EFI_VARIABLE_APPEND_WRITE);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+
+	/* Overwrite variable with the same timestamp. Should not succeed, because the timestamp was not compromised */
+	status = m_client->set_variable(m_common_guid, u"var", VAR_auth, sizeof(VAR_auth),
+					m_authentication_common_attributes);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SECURITY_VIOLATION, status);
+
+	/* Delete variable */
+	status = m_client->set_variable(m_common_guid, u"var", VAR_delete_auth,
+					sizeof(VAR_delete_auth),
+					m_authentication_common_attributes);
+	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
+}
+
+TEST(SmmVariableServiceTests, bootVarAuthenticationDisabled)
+{
+	efi_status_t status;
+	std::string read_data;
+
+	/* Without PK the authentication is disabled so each variable are writable, even in wrong order */
 	status = m_client->set_variable(m_security_database_guid, u"db", (uint8_t *)DB1_auth,
 					sizeof(DB1_auth), m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
@@ -778,26 +839,21 @@
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 }
 
-TEST(SmmVariableServiceTests, authenticationSetAllKeys)
+TEST(SmmVariableServiceTests, bootVarAuthenticationSetAllKeys)
 {
 	efi_status_t status;
-	std::string read_data;
 
 	/* Enable authentication via setting PK */
 	status = m_client->set_variable(m_global_guid, u"PK", PK1_auth, sizeof(PK1_auth),
 					m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 
-	/* Try setting db1 and custom variable without KEK */
+	/* Try setting db1 without KEK */
 	status = m_client->set_variable(m_security_database_guid, u"db", DB1_auth,
 					sizeof(DB1_auth), m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SECURITY_VIOLATION, status);
 
-	status = m_client->set_variable(m_common_guid, u"var", VAR_auth, sizeof(VAR_auth),
-					m_authentication_common_attributes);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SECURITY_VIOLATION, status);
-
-	/* Set db2 that was signed by OK */
+	/* Set db2 that was signed by PK */
 	status = m_client->set_variable(m_security_database_guid, u"db", DB2_auth,
 					sizeof(DB2_auth), m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
@@ -807,42 +863,13 @@
 					m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 
-	/* Try setting custom variable with wrong db */
-	status = m_client->set_variable(m_common_guid, u"var", VAR_auth, sizeof(VAR_auth),
-					m_authentication_common_attributes);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SECURITY_VIOLATION, status);
-
-	/* Set db and var and then overwrite var */
+	/* Set db */
 	status = m_client->set_variable(m_security_database_guid, u"db", DB1_auth,
 					sizeof(DB1_auth), m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
-
-	/* The variable is not yet set */
-	status = m_client->get_variable(m_common_guid, u"var", read_data);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
-
-	/* Set variable */
-	status = m_client->set_variable(m_common_guid, u"var", VAR_auth, sizeof(VAR_auth),
-					m_authentication_common_attributes);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
-
-	/* Get and validate variable value */
-	status = m_client->get_variable(m_common_guid, u"var", read_data);
-	UNSIGNED_LONGS_EQUAL(var_data_txt_len, read_data.size());
-	MEMCMP_EQUAL(var_data_txt, read_data.c_str(), var_data_txt_len);
-
-	/* Set variable with empty payload */
-	status = m_client->set_variable(m_common_guid, u"var", VAR_delete_auth,
-					sizeof(VAR_delete_auth),
-					m_authentication_common_attributes);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
-
-	/* Check if it doesn't exist */
-	status = m_client->get_variable(m_common_guid, u"var", read_data);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_NOT_FOUND, status);
 }
 
-TEST(SmmVariableServiceTests, authenticationDelete)
+TEST(SmmVariableServiceTests, bootVarAuthenticationRemove)
 {
 	efi_status_t status;
 
@@ -856,11 +883,7 @@
 					m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 
-	status = m_client->set_variable(m_security_database_guid, u"db", DB1_auth,
-					sizeof(DB1_auth), m_authentication_common_attributes);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
-
-	/* Remove KEK and try overwriting db with a valid request which should fail without KEK */
+	/* Remove KEK and try writing db with a valid request which should fail without KEK */
 	status = m_client->set_variable(m_global_guid, u"KEK", KEK_delete_auth,
 					sizeof(KEK_delete_auth),
 					m_authentication_common_attributes);
@@ -870,11 +893,6 @@
 					sizeof(DB1_auth), m_authentication_common_attributes);
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SECURITY_VIOLATION, status);
 
-	/* Although db was not overwritten the original value is still available to verify the custom variable */
-	status = m_client->set_variable(m_common_guid, u"var", VAR_auth, sizeof(VAR_auth),
-					m_authentication_common_attributes);
-	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
-
 	/* Try removing PK with an incorrect, non-authenticated delete request */
 	status = m_client->remove_variable(m_global_guid, u"PK");
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SECURITY_VIOLATION, status);
@@ -890,7 +908,7 @@
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 }
 
-TEST(SmmVariableServiceTests, authenticationChangePK)
+TEST(SmmVariableServiceTests, bootVarAuthenticationChangePK)
 {
 	efi_status_t status;
 
@@ -916,7 +934,7 @@
 	UNSIGNED_LONGLONGS_EQUAL(EFI_SUCCESS, status);
 }
 
-TEST(SmmVariableServiceTests, authenticationSignatureVerifyFailure)
+TEST(SmmVariableServiceTests, bootVarAuthenticationSignatureVerifyFailure)
 {
 	efi_status_t status;
 
diff --git a/deployments/attestation/config/default-opteesp/CMakeLists.txt b/deployments/attestation/config/default-opteesp/CMakeLists.txt
index b755c15..351a568 100644
--- a/deployments/attestation/config/default-opteesp/CMakeLists.txt
+++ b/deployments/attestation/config/default-opteesp/CMakeLists.txt
@@ -80,7 +80,6 @@
 #TODO: api headers
 
 install(TARGETS attestation
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/attestation/config/default-opteesp/default_attestation.dts.in b/deployments/attestation/config/default-opteesp/default_attestation.dts.in
index e310cc6..70f99ec 100644
--- a/deployments/attestation/config/default-opteesp/default_attestation.dts.in
+++ b/deployments/attestation/config/default-opteesp/default_attestation.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "Attestation";
 	execution-ctx-count = <1>;
diff --git a/deployments/attestation/config/default-sp/CMakeLists.txt b/deployments/attestation/config/default-sp/CMakeLists.txt
index 3c7a598..6708193 100644
--- a/deployments/attestation/config/default-sp/CMakeLists.txt
+++ b/deployments/attestation/config/default-sp/CMakeLists.txt
@@ -83,7 +83,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS attestation
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/attestation/config/default-sp/default_attestation.dts.in b/deployments/attestation/config/default-sp/default_attestation.dts.in
index e8383ae..393ea52 100644
--- a/deployments/attestation/config/default-sp/default_attestation.dts.in
+++ b/deployments/attestation/config/default-sp/default_attestation.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "Attestation";
 	execution-ctx-count = <1>;
diff --git a/deployments/attestation/env/commonsp/attestation_sp.c b/deployments/attestation/env/commonsp/attestation_sp.c
index 53b8f8e..d82c217 100644
--- a/deployments/attestation/env/commonsp/attestation_sp.c
+++ b/deployments/attestation/env/commonsp/attestation_sp.c
@@ -179,6 +179,22 @@
 	(void)interrupt_id;
 }
 
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
 static bool sp_init(uint16_t *own_id)
 {
 	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
diff --git a/deployments/block-storage/config/cfi-flash-optee/CMakeLists.txt b/deployments/block-storage/config/cfi-flash-optee/CMakeLists.txt
index bd464a2..e351b53 100644
--- a/deployments/block-storage/config/cfi-flash-optee/CMakeLists.txt
+++ b/deployments/block-storage/config/cfi-flash-optee/CMakeLists.txt
@@ -88,7 +88,6 @@
 endif()
 
 install(TARGETS block-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/block-storage/config/cfi-flash-optee/default_block-storage.dts.in b/deployments/block-storage/config/cfi-flash-optee/default_block-storage.dts.in
index 287ecb0..bc65a37 100644
--- a/deployments/block-storage/config/cfi-flash-optee/default_block-storage.dts.in
+++ b/deployments/block-storage/config/cfi-flash-optee/default_block-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "BlockStorage";
 	execution-ctx-count = <1>;
diff --git a/deployments/block-storage/config/default-opteesp/CMakeLists.txt b/deployments/block-storage/config/default-opteesp/CMakeLists.txt
index 86ffe3f..0d7834e 100644
--- a/deployments/block-storage/config/default-opteesp/CMakeLists.txt
+++ b/deployments/block-storage/config/default-opteesp/CMakeLists.txt
@@ -66,7 +66,6 @@
 endif()
 
 install(TARGETS block-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/block-storage/config/default-opteesp/default_block-storage.dts.in b/deployments/block-storage/config/default-opteesp/default_block-storage.dts.in
index 287ecb0..bc65a37 100644
--- a/deployments/block-storage/config/default-opteesp/default_block-storage.dts.in
+++ b/deployments/block-storage/config/default-opteesp/default_block-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "BlockStorage";
 	execution-ctx-count = <1>;
diff --git a/deployments/block-storage/config/default-sp/CMakeLists.txt b/deployments/block-storage/config/default-sp/CMakeLists.txt
index 6802aa1..f6bf617 100644
--- a/deployments/block-storage/config/default-sp/CMakeLists.txt
+++ b/deployments/block-storage/config/default-sp/CMakeLists.txt
@@ -71,7 +71,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS block-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/block-storage/config/default-sp/default_block-storage.dts.in b/deployments/block-storage/config/default-sp/default_block-storage.dts.in
index 916925b..b7b10e5 100644
--- a/deployments/block-storage/config/default-sp/default_block-storage.dts.in
+++ b/deployments/block-storage/config/default-sp/default_block-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "BlockStorage";
 	execution-ctx-count = <1>;
diff --git a/deployments/block-storage/config/edk2-secure-flash-opteesp/CMakeLists.txt b/deployments/block-storage/config/edk2-secure-flash-opteesp/CMakeLists.txt
index 6e6fc2d..039fcb4 100644
--- a/deployments/block-storage/config/edk2-secure-flash-opteesp/CMakeLists.txt
+++ b/deployments/block-storage/config/edk2-secure-flash-opteesp/CMakeLists.txt
@@ -89,7 +89,6 @@
 endif()
 
 install(TARGETS block-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/block-storage/config/edk2-secure-flash-opteesp/default_block-storage.dts.in b/deployments/block-storage/config/edk2-secure-flash-opteesp/default_block-storage.dts.in
index 287ecb0..bc65a37 100644
--- a/deployments/block-storage/config/edk2-secure-flash-opteesp/default_block-storage.dts.in
+++ b/deployments/block-storage/config/edk2-secure-flash-opteesp/default_block-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "BlockStorage";
 	execution-ctx-count = <1>;
diff --git a/deployments/block-storage/config/semihosted-opteesp/CMakeLists.txt b/deployments/block-storage/config/semihosted-opteesp/CMakeLists.txt
index 7ad9c0b..c34282f 100644
--- a/deployments/block-storage/config/semihosted-opteesp/CMakeLists.txt
+++ b/deployments/block-storage/config/semihosted-opteesp/CMakeLists.txt
@@ -85,7 +85,6 @@
 endif()
 
 install(TARGETS block-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/block-storage/config/semihosted-opteesp/default_block-storage.dts.in b/deployments/block-storage/config/semihosted-opteesp/default_block-storage.dts.in
index 287ecb0..bc65a37 100644
--- a/deployments/block-storage/config/semihosted-opteesp/default_block-storage.dts.in
+++ b/deployments/block-storage/config/semihosted-opteesp/default_block-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "BlockStorage";
 	execution-ctx-count = <1>;
diff --git a/deployments/block-storage/env/commonsp/block_storage_sp.c b/deployments/block-storage/env/commonsp/block_storage_sp.c
index 8b0c1fd..9c2ab03 100644
--- a/deployments/block-storage/env/commonsp/block_storage_sp.c
+++ b/deployments/block-storage/env/commonsp/block_storage_sp.c
@@ -111,6 +111,22 @@
 	(void)interrupt_id;
 }
 
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
 static bool sp_init(uint16_t *own_id)
 {
 	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
diff --git a/deployments/component-test/component-test.cmake b/deployments/component-test/component-test.cmake
index 64f7543..c20e2fe 100644
--- a/deployments/component-test/component-test.cmake
+++ b/deployments/component-test/component-test.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -38,6 +38,7 @@
 		"components/common/endian/test"
 		"components/common/crc32"
 		"components/common/crc32/test"
+		"components/common/mbedtls"
 		"components/config/ramstore"
 		"components/config/ramstore/test"
 		"components/messaging/ffa/libsp/mock"
@@ -105,6 +106,7 @@
 		"components/service/block_storage/factory/client"
 		"components/service/block_storage/factory/rpmb"
 		"components/service/fwu/agent"
+		"components/service/fwu/common"
 		"components/service/fwu/fw_store/banked"
 		"components/service/fwu/fw_store/banked/metadata_serializer/v1"
 		"components/service/fwu/fw_store/banked/metadata_serializer/v2"
@@ -119,7 +121,11 @@
 		"components/service/fwu/inspector/mock"
 		"components/service/fwu/inspector/direct"
 		"components/service/fwu/provider"
-		"components/service/fwu/provider/serializer/packed-c"
+		"components/service/fwu/provider/serializer"
+		"components/service/fwu/psa_fwu_m/agent"
+		"components/service/fwu/psa_fwu_m/agent/test"
+		"components/service/fwu/psa_fwu_m/interface/mock"
+		"components/service/fwu/psa_fwu_m/interface/mock/test"
 		"components/service/fwu/test/fwu_client/direct"
 		"components/service/fwu/test/fwu_dut"
 		"components/service/fwu/test/fwu_dut/sim"
@@ -234,7 +240,7 @@
 protobuf_generate_all(TGT "component-test" NAMESPACE "protobuf" BASE_DIR "${TS_ROOT}/protocols")
 
 # MbedTLS
-set(MBEDTLS_USER_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/libmbedx509.h"
+set(MBEDTLS_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/crypto_provider_x509.h"
 	CACHE STRING "Configuration file for Mbed TLS" FORCE)
 include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
 target_link_libraries(component-test PRIVATE MbedTLS::mbedcrypto)
@@ -242,7 +248,7 @@
 
 # Pass the location of the mbedtls config file to C preprocessor.
 target_compile_definitions(component-test PRIVATE
-		MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}"
+		MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}"
 )
 
 # Qcbor
diff --git a/deployments/crypto/config/default-opteesp/CMakeLists.txt b/deployments/crypto/config/default-opteesp/CMakeLists.txt
index f5c7399..5c12af8 100644
--- a/deployments/crypto/config/default-opteesp/CMakeLists.txt
+++ b/deployments/crypto/config/default-opteesp/CMakeLists.txt
@@ -81,7 +81,6 @@
 #TODO: api headers
 
 install(TARGETS crypto
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/crypto/config/default-opteesp/default_crypto.dts.in b/deployments/crypto/config/default-opteesp/default_crypto.dts.in
index 729dca7..68dbb48 100644
--- a/deployments/crypto/config/default-opteesp/default_crypto.dts.in
+++ b/deployments/crypto/config/default-opteesp/default_crypto.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "Crypto";
 	execution-ctx-count = <1>;
diff --git a/deployments/crypto/config/default-sp/CMakeLists.txt b/deployments/crypto/config/default-sp/CMakeLists.txt
index 7559c1b..aab0d57 100644
--- a/deployments/crypto/config/default-sp/CMakeLists.txt
+++ b/deployments/crypto/config/default-sp/CMakeLists.txt
@@ -84,7 +84,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS crypto
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/crypto/config/default-sp/default_crypto.dts.in b/deployments/crypto/config/default-sp/default_crypto.dts.in
index ef63c63..6c44a0c 100644
--- a/deployments/crypto/config/default-sp/default_crypto.dts.in
+++ b/deployments/crypto/config/default-sp/default_crypto.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "Crypto";
 	execution-ctx-count = <1>;
diff --git a/deployments/crypto/crypto.cmake b/deployments/crypto/crypto.cmake
index 098861c..9dad507 100644
--- a/deployments/crypto/crypto.cmake
+++ b/deployments/crypto/crypto.cmake
@@ -8,6 +8,7 @@
 add_components(TARGET "crypto"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"components/common/mbedtls"
 		"components/common/tlv"
 		"components/rpc/common/interface"
 		"components/rpc/common/endpoint"
@@ -46,7 +47,7 @@
 protobuf_generate_all(TGT "crypto" NAMESPACE "protobuf" BASE_DIR "${TS_ROOT}/protocols")
 
 # Mbed TLS provides libmbedcrypto
-set(MBEDTLS_USER_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/libmbedx509.h"
+set(MBEDTLS_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/crypto_provider_x509.h"
 	CACHE STRING "Configuration file for Mbed TLS" FORCE)
 include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
 target_link_libraries(crypto PRIVATE MbedTLS::mbedcrypto)
@@ -55,7 +56,7 @@
 # Provide the config path to mbedtls
 target_compile_definitions(crypto
 	PRIVATE
-		MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}"
+		MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}"
 )
 
 #################################################################
diff --git a/deployments/crypto/env/commonsp/crypto_sp.c b/deployments/crypto/env/commonsp/crypto_sp.c
index 7c84147..68c6f9d 100644
--- a/deployments/crypto/env/commonsp/crypto_sp.c
+++ b/deployments/crypto/env/commonsp/crypto_sp.c
@@ -137,6 +137,22 @@
 	(void)interrupt_id;
 }
 
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
 static bool sp_init(uint16_t *own_id)
 {
 	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
diff --git a/deployments/deployment.cmake b/deployments/deployment.cmake
index 76b0f18..5285ead 100644
--- a/deployments/deployment.cmake
+++ b/deployments/deployment.cmake
@@ -62,8 +62,12 @@
   set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type.")
 endif()
 
+if (COVERAGE)
+	set(CMAKE_BUILD_TYPE "DebugCoverage" CACHE STRING "Build type" FORCE)
+endif()
+
 # List of supported build types. Needs to be in alignment with the toolchain file
-set(TS_SUPPORTED_BUILD_TYPES DEBUG "MINSIZEREL" "MINSIZWITHDEBINFO" "RELEASE" "RELWITHDEBINFO" CACHE
+set(TS_SUPPORTED_BUILD_TYPES "DEBUG" "MINSIZEREL" "MINSIZWITHDEBINFO" "RELEASE" "RELWITHDEBINFO" "DEBUGCOVERAGE" CACHE
   STRING "List of supported build types.")
 
 # Convert the build type string to upper case to help case insensitive comparison.
@@ -75,5 +79,9 @@
 	message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\" specified in CMAKE_BUILD_TYPE.")
 endif()
 
+# Set postfix of libraries according the build type.
+set(CMAKE_DEBUGCOVERAGE_POSTFIX "c")
+set(CMAKE_DEBUG_POSTFIX "d")
+
 # Default protocol UUID used by TS SPs.
 set(TS_RPC_UUID_CANON "bdcd76d7-825e-4751-963b-86d4f84943ac" CACHE STRING "Trusted Services PRC (protocol) UUID.")
diff --git a/deployments/env-test/config/baremetal-fvp_base_revc-opteesp/default_env-test.dts.in b/deployments/env-test/config/baremetal-fvp_base_revc-opteesp/default_env-test.dts.in
index 3083edc..33a20e1 100644
--- a/deployments/env-test/config/baremetal-fvp_base_revc-opteesp/default_env-test.dts.in
+++ b/deployments/env-test/config/baremetal-fvp_base_revc-opteesp/default_env-test.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "EnvTest";
 	execution-ctx-count = <1>;
@@ -27,7 +27,7 @@
 		test-memory {
 			description = "test-memory";
 			pages-count = <4>;
-			attributes = <0x7>; /* read-write-execute */
+			attributes = <0x3>; /* read-write */
 		};
 	};
 
diff --git a/deployments/env-test/config/baremetal-fvp_base_revc-sp/default_env-test.dts.in b/deployments/env-test/config/baremetal-fvp_base_revc-sp/default_env-test.dts.in
index 379eba3..5dd3060 100644
--- a/deployments/env-test/config/baremetal-fvp_base_revc-sp/default_env-test.dts.in
+++ b/deployments/env-test/config/baremetal-fvp_base_revc-sp/default_env-test.dts.in
@@ -6,7 +6,7 @@
 @DTS_TAG@
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "EnvTest";
 	execution-ctx-count = <1>;
@@ -23,7 +23,7 @@
 		test-memory {
 			description = "test-memory";
 			pages-count = <4>;
-			attributes = <0x7>; /* read-write-execute */
+			attributes = <0x3>; /* read-write */
 		};
 	};
 	device-regions {
diff --git a/deployments/env-test/config/n1sdp-opteesp/CMakeLists.txt b/deployments/env-test/config/n1sdp-opteesp/CMakeLists.txt
index ef2d02d..5b7ba83 100644
--- a/deployments/env-test/config/n1sdp-opteesp/CMakeLists.txt
+++ b/deployments/env-test/config/n1sdp-opteesp/CMakeLists.txt
@@ -75,7 +75,6 @@
 #TODO: api headers
 
 install(TARGETS env-test
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/env-test/config/n1sdp-opteesp/default_env-test.dts.in b/deployments/env-test/config/n1sdp-opteesp/default_env-test.dts.in
index c8c8c38..39d2fb2 100644
--- a/deployments/env-test/config/n1sdp-opteesp/default_env-test.dts.in
+++ b/deployments/env-test/config/n1sdp-opteesp/default_env-test.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "EnvTest";
 	execution-ctx-count = <1>;
@@ -27,7 +27,7 @@
 		test-memory {
 			description = "test-memory";
 			pages-count = <4>;
-			attributes = <0x7>; /* read-write-execute */
+			attributes = <0x3>; /* read-write */
 		};
 	};
 
diff --git a/deployments/env-test/env/commonsp/env_test_sp.c b/deployments/env-test/env/commonsp/env_test_sp.c
index daaf50a..5635a72 100644
--- a/deployments/env-test/env/commonsp/env_test_sp.c
+++ b/deployments/env-test/env/commonsp/env_test_sp.c
@@ -102,6 +102,22 @@
 	(void)interrupt_id;
 }
 
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
 static bool sp_init(uint16_t *own_id)
 {
 	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
diff --git a/deployments/env-test/suites/baremetal-tests.cmake b/deployments/env-test/suites/baremetal-tests.cmake
index c4cf92a..23b6029 100644
--- a/deployments/env-test/suites/baremetal-tests.cmake
+++ b/deployments/env-test/suites/baremetal-tests.cmake
@@ -15,7 +15,6 @@
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
 		"components/common/uuid"
-		"components/service/crypto/backend/mbedcrypto"
 		"components/service/crypto/backend/mbedcrypto/trng_adapter/platform"
 		"components/service/crypto/backend/mbedcrypto/trng_adapter/test"
 		"components/service/secure_storage/include"
@@ -37,23 +36,6 @@
 )
 
 #-------------------------------------------------------------------------------
-#  Components used from external projects
-#
-#-------------------------------------------------------------------------------
-
-# Mbed TLS provides libmbedcrypto
-set(MBEDTLS_USER_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/libmbed_only.h"
-	CACHE STRING "Configuration file for Mbed TLS" FORCE)
-include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
-target_link_libraries(env-test PRIVATE MbedTLS::mbedcrypto)
-
-# Provide the config path to mbedtls
-target_compile_definitions(env-test
-	PRIVATE
-		MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}"
-)
-
-#-------------------------------------------------------------------------------
 #  This test suite depends on platform specific drivers
 #
 #-------------------------------------------------------------------------------
diff --git a/deployments/fwu-tool/fwu.cmake b/deployments/fwu-tool/fwu.cmake
index d9cac39..fdaa550 100644
--- a/deployments/fwu-tool/fwu.cmake
+++ b/deployments/fwu-tool/fwu.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -24,6 +24,7 @@
 		"components/media/volume/index"
 		"components/service/common/include"
 		"components/service/fwu/agent"
+		"components/service/fwu/common"
 		"components/service/fwu/config"
 		"components/service/fwu/config/gpt"
 		"components/service/fwu/fw_store/banked"
diff --git a/deployments/fwu/config/default-opteesp/CMakeLists.txt b/deployments/fwu/config/default-opteesp/CMakeLists.txt
index 943ca56..a4ca84c 100644
--- a/deployments/fwu/config/default-opteesp/CMakeLists.txt
+++ b/deployments/fwu/config/default-opteesp/CMakeLists.txt
@@ -80,7 +80,6 @@
 #TODO: api headers
 
 install(TARGETS fwu
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/fwu/config/default-opteesp/default_fwu.dts.in b/deployments/fwu/config/default-opteesp/default_fwu.dts.in
index d62850f..21fb51f 100644
--- a/deployments/fwu/config/default-opteesp/default_fwu.dts.in
+++ b/deployments/fwu/config/default-opteesp/default_fwu.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "FWU";
 	execution-ctx-count = <1>;
diff --git a/deployments/fwu/config/default-sp/CMakeLists.txt b/deployments/fwu/config/default-sp/CMakeLists.txt
index dc10c29..b105ea4 100644
--- a/deployments/fwu/config/default-sp/CMakeLists.txt
+++ b/deployments/fwu/config/default-sp/CMakeLists.txt
@@ -83,7 +83,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS fwu
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/fwu/config/default-sp/default_fwu.dts.in b/deployments/fwu/config/default-sp/default_fwu.dts.in
index a30111a..83249d9 100644
--- a/deployments/fwu/config/default-sp/default_fwu.dts.in
+++ b/deployments/fwu/config/default-sp/default_fwu.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "FWU";
 	execution-ctx-count = <1>;
diff --git a/deployments/fwu/env/commonsp/fwu_sp.c b/deployments/fwu/env/commonsp/fwu_sp.c
index e3e0544..cf1e6ff 100644
--- a/deployments/fwu/env/commonsp/fwu_sp.c
+++ b/deployments/fwu/env/commonsp/fwu_sp.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
  */
 
 #include <stddef.h>
@@ -20,7 +20,7 @@
 #include "service/fwu/fw_store/banked/metadata_serializer/v2/metadata_serializer_v2.h"
 #include "service/fwu/inspector/direct/direct_fw_inspector.h"
 #include "service/fwu/provider/fwu_provider.h"
-#include "service/fwu/provider/serializer/packed-c/packedc_fwu_provider_serializer.h"
+#include "service/log/factory/log_factory.h"
 #include "sp_api.h"
 #include "sp_discovery.h"
 #include "sp_messaging.h"
@@ -45,7 +45,7 @@
 	struct ts_rpc_endpoint_sp rpc_endpoint = { 0 };
 	struct fwu_provider service_provider = { 0 };
 	struct rpc_service_interface *service_iface = NULL;
-	struct update_agent update_agent = { 0 };
+	struct update_agent *update_agent = NULL;
 	struct fw_store fw_store = { 0 };
 	struct sp_msg req_msg = { 0 };
 	struct sp_msg resp_msg = { 0 };
@@ -89,23 +89,21 @@
 		goto fatal_error;
 	}
 
-	if (update_agent_init(&update_agent, HARD_CODED_BOOT_INDEX, direct_fw_inspector_inspect,
-			      &fw_store)) {
+	update_agent = update_agent_init(HARD_CODED_BOOT_INDEX, direct_fw_inspector_inspect,
+					 &fw_store);
+	if (!update_agent) {
 		EMSG("Failed to init update agent");
 		goto fatal_error;
 	}
 
 	/* Initialise the FWU service provider */
-	service_iface = fwu_provider_init(&service_provider, &update_agent);
+	service_iface = fwu_provider_init(&service_provider, update_agent);
 
 	if (!service_iface) {
 		EMSG("Failed to init service provider");
 		goto fatal_error;
 	}
 
-	fwu_provider_register_serializer(&service_provider, TS_RPC_ENCODING_PACKED_C,
-					 packedc_fwu_provider_serializer_instance());
-
 	/* Associate service interface with FFA call endpoint */
 	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 1, 16);
 	if (rpc_status != RPC_SUCCESS) {
@@ -152,6 +150,22 @@
 	(void)interrupt_id;
 }
 
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
 static bool sp_init(uint16_t *own_id)
 {
 	static uint8_t tx_buffer[4096] __aligned(4096);
@@ -163,6 +177,13 @@
 		return false;
 	}
 
+	IMSG("Start discovering logging service");
+	if (log_factory_create()) {
+		IMSG("Logging service discovery successful");
+	} else {
+		EMSG("Logging service discovery failed, falling back to console log");
+	}
+
 	sp_res = sp_discovery_own_id_get(own_id);
 	if (sp_res != SP_RESULT_OK) {
 		EMSG("Failed to query own ID: %d", sp_res);
diff --git a/deployments/fwu/env/commonsp/fwu_sp.cmake b/deployments/fwu/env/commonsp/fwu_sp.cmake
index 2fd8ca7..1ca1e86 100644
--- a/deployments/fwu/env/commonsp/fwu_sp.cmake
+++ b/deployments/fwu/env/commonsp/fwu_sp.cmake
@@ -27,7 +27,7 @@
 		"components/rpc/ts_rpc/endpoint/sp"
 		"components/service/common/provider"
 		"components/service/fwu/provider"
-		"components/service/fwu/provider/serializer/packed-c"
+		"components/service/fwu/provider/serializer"
 )
 
 target_sources(fwu PRIVATE
diff --git a/deployments/fwu/fwu.cmake b/deployments/fwu/fwu.cmake
index 7276360..90a73d9 100644
--- a/deployments/fwu/fwu.cmake
+++ b/deployments/fwu/fwu.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -19,6 +19,7 @@
 		"components/media/volume/index"
 		"components/service/common/include"
 		"components/service/fwu/agent"
+		"components/service/fwu/common"
 		"components/service/fwu/config"
 		"components/service/fwu/config/gpt"
 		"components/service/fwu/fw_store/banked"
@@ -29,6 +30,11 @@
 		"components/service/fwu/installer/copy"
 		"components/service/fwu/installer/factory/default"
 		"components/service/fwu/inspector/direct"
+		"components/service/log/factory"
+		"components/service/log/client"
+		"components/rpc/common/caller"
+		"components/rpc/ts_rpc/caller/sp"
+		"components/service/common/client"
 )
 
 #################################################################
diff --git a/deployments/internal-trusted-storage/config/default-opteesp/CMakeLists.txt b/deployments/internal-trusted-storage/config/default-opteesp/CMakeLists.txt
index 4c39da5..dd1058a 100644
--- a/deployments/internal-trusted-storage/config/default-opteesp/CMakeLists.txt
+++ b/deployments/internal-trusted-storage/config/default-opteesp/CMakeLists.txt
@@ -74,7 +74,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS internal-trusted-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/internal-trusted-storage/config/default-opteesp/default_internal-trusted-storage.dts.in b/deployments/internal-trusted-storage/config/default-opteesp/default_internal-trusted-storage.dts.in
index 9c5c897..fa3db83 100644
--- a/deployments/internal-trusted-storage/config/default-opteesp/default_internal-trusted-storage.dts.in
+++ b/deployments/internal-trusted-storage/config/default-opteesp/default_internal-trusted-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "ITS";
 	execution-ctx-count = <1>;
diff --git a/deployments/internal-trusted-storage/config/default-sp/CMakeLists.txt b/deployments/internal-trusted-storage/config/default-sp/CMakeLists.txt
index f1c49d6..ffaa994 100644
--- a/deployments/internal-trusted-storage/config/default-sp/CMakeLists.txt
+++ b/deployments/internal-trusted-storage/config/default-sp/CMakeLists.txt
@@ -78,7 +78,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS internal-trusted-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/internal-trusted-storage/config/default-sp/default_internal-trusted-storage.dts.in b/deployments/internal-trusted-storage/config/default-sp/default_internal-trusted-storage.dts.in
index 068ecc0..87b8051 100644
--- a/deployments/internal-trusted-storage/config/default-sp/default_internal-trusted-storage.dts.in
+++ b/deployments/internal-trusted-storage/config/default-sp/default_internal-trusted-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "ITS";
 	execution-ctx-count = <1>;
diff --git a/deployments/internal-trusted-storage/config/shared-flash-opteesp/CMakeLists.txt b/deployments/internal-trusted-storage/config/shared-flash-opteesp/CMakeLists.txt
index 9b340e2..6ff934b 100644
--- a/deployments/internal-trusted-storage/config/shared-flash-opteesp/CMakeLists.txt
+++ b/deployments/internal-trusted-storage/config/shared-flash-opteesp/CMakeLists.txt
@@ -67,7 +67,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS internal-trusted-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/internal-trusted-storage/config/shared-flash-opteesp/default_internal-trusted-storage.dts.in b/deployments/internal-trusted-storage/config/shared-flash-opteesp/default_internal-trusted-storage.dts.in
index 9c5c897..fa3db83 100644
--- a/deployments/internal-trusted-storage/config/shared-flash-opteesp/default_internal-trusted-storage.dts.in
+++ b/deployments/internal-trusted-storage/config/shared-flash-opteesp/default_internal-trusted-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "ITS";
 	execution-ctx-count = <1>;
diff --git a/deployments/internal-trusted-storage/env/commonsp/its_sp.c b/deployments/internal-trusted-storage/env/commonsp/its_sp.c
index 7bcae85..f123be7 100644
--- a/deployments/internal-trusted-storage/env/commonsp/its_sp.c
+++ b/deployments/internal-trusted-storage/env/commonsp/its_sp.c
@@ -110,3 +110,19 @@
 {
 	(void)interrupt_id;
 }
+
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
diff --git a/deployments/libpsats/arm-linux/CMakeLists.txt b/deployments/libpsats/arm-linux/CMakeLists.txt
new file mode 100644
index 0000000..20e4f1b
--- /dev/null
+++ b/deployments/libpsats/arm-linux/CMakeLists.txt
@@ -0,0 +1,44 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
+include(../../deployment.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+#  Options and variables
+#-------------------------------------------------------------------------------
+set(BUILD_SHARED_LIBS On CACHE BOOL "Determine if a shared library is being built.")
+if(NOT BUILD_SHARED_LIBS)
+	message(FATAL_ERROR "Building static library is not yet supported. Call cmake with -DBUILD_SHARED_LIBS=1")
+endif()
+
+#-------------------------------------------------------------------------------
+#  The CMakeLists.txt for building the libpsats deployment for arm-linux
+#
+#  Used for building the libpsats library for the arm-linux environment. Used for
+#  locating and accessing services from a Linux userspace client. Service
+#  instances can be located in any supported secure processing environment.
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/environments/arm-linux/env_shared_lib.cmake)
+project(psats LANGUAGES CXX C)
+
+add_library(psats)
+
+target_include_directories(psats PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+#-------------------------------------------------------------------------------
+#  For user-specific tracing set to TRACE_LEVEL_NONE and implement:
+#  void trace_puts(const char *str)
+#-------------------------------------------------------------------------------
+
+set(TRACE_PREFIX "LIBPSATS" CACHE STRING "Trace prefix")
+set(TRACE_LEVEL "TRACE_LEVEL_DEBUG" CACHE STRING "Trace level")
+#-------------------------------------------------------------------------------
+#  Extend with components that are common across all deployments of
+#  libpsats
+#
+#-------------------------------------------------------------------------------
+include(../libpsats.cmake REQUIRED)
diff --git a/deployments/libpsats/libpsats-import.cmake b/deployments/libpsats/libpsats-import.cmake
new file mode 100644
index 0000000..9c44ca7
--- /dev/null
+++ b/deployments/libpsats/libpsats-import.cmake
@@ -0,0 +1,114 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+# Import libpsats into a dependent in-tree deployment build.  Where another
+# deployment uses libpsats, including this file in the dependent deployment
+# CMake build file allows libpsats to be built and installed into the binary
+# directory of the dependent.
+#-------------------------------------------------------------------------------
+option(CFG_FORCE_PREBUILT_LIBPSATS Off)
+# Try to find a pre-build package.
+version_semver_read(FILE "${CMAKE_CURRENT_LIST_DIR}/version.txt" MAJOR _major MINOR _minor PATCH _patch)
+set(_verstring "${_major}.${_minor}.${_patch}")
+
+if (COVERAGE)
+	set(LIBPSATS_BUILD_TYPE "DebugCoverage" CACHE STRING "Build type." FORCE)
+endif()
+
+find_package(libpsats "${_verstring}" QUIET PATHS ${CMAKE_CURRENT_BINARY_DIR}/libpsats_install/${TS_ENV}/lib/cmake/libpsats)
+if(NOT libpsats_FOUND)
+	if (CFG_FORCE_PREBUILT_LIBPSATS)
+		string(CONCAT _msg "find_package() failed to find the \"libpsats\" package. Please pass -Dlibpsats_ROOT=<full path>"
+							" to cmake, where <full path> is the directory of the libpsatsConfig.cmake file, or "
+							" pass -DCMAKE_FIND_ROOT_PATH=<path>, where <path> is the INSTALL_PREFIX used"
+							" when building libpsats. libpsats_ROOT can be set in the environment too."
+						   "If you wish to debug the search process pass -DCMAKE_FIND_DEBUG_MODE=ON to cmake.")
+		message(FATAL_ERROR ${_msg})
+	endif()
+	# Set build type, if a specific value is required. This leaves the default value in the hands of the
+	# libpsats deployment being built.
+	if (DEFINED LIBPSATS_BUILD_TYPE)
+		set(_libpsats_build_type_arg "-DCMAKE_BUILD_TYPE=${LIBPSATS_BUILD_TYPE}")
+	endif()
+
+	# If not successful, build libpsats as a sub-project.
+	execute_process(COMMAND
+		${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
+		${CMAKE_COMMAND}
+			${_libpsats_build_type_arg}
+			-S ${TS_ROOT}/deployments/libpsats/${TS_ENV}
+			-B ${CMAKE_CURRENT_BINARY_DIR}/libpsats
+		RESULT_VARIABLE
+			_exec_error
+		)
+	unset(_libpsats_build_type_arg)
+	if (NOT _exec_error EQUAL 0)
+		message(FATAL_ERROR "Configuring libpsats failed. ${_exec_error}")
+	endif()
+	execute_process(COMMAND
+		${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
+		${CMAKE_COMMAND}
+			--build ${CMAKE_CURRENT_BINARY_DIR}/libpsats
+			--parallel ${PROCESSOR_COUNT}
+		RESULT_VARIABLE
+			_exec_error
+		)
+	if (NOT _exec_error EQUAL 0)
+		message(FATAL_ERROR "Installing libpsats failed. ${_exec_error}")
+	endif()
+	execute_process(COMMAND
+		${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
+		${CMAKE_COMMAND}
+			--install ${CMAKE_CURRENT_BINARY_DIR}/libpsats
+			--prefix ${CMAKE_CURRENT_BINARY_DIR}/libpsats_install
+		RESULT_VARIABLE
+			_exec_error
+		)
+	if (NOT _exec_error EQUAL 0)
+		message(FATAL_ERROR "Installing libpsats failed. ${_exec_error}")
+	endif()
+
+	install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/libpsats/cmake_install.cmake)
+
+	find_package(libpsats "${_verstring}" QUIET REQUIRED PATHS ${CMAKE_CURRENT_BINARY_DIR}/libpsats_install/${TS_ENV}/lib/cmake/libpsats)
+else()
+	message(STATUS "Using prebuilt libpsats from ${libpsats_DIR}")
+endif()
+
+# Cmake will use the same build type of the imported target as used by the main project. If no mapping is configured and
+# the matching build type is not found, cmake will fall back to any build type. Details of the fall back mechanism are not
+# documented.
+# If a mapping is defined, and the imported target does not define the mapped build type, cmake will treat the library
+# as not found.
+#
+# If LIBPSATS_BUILD_TYPE is set and the main project wants to use a specific build type, configure build type mapping to
+# only allow using the requested build type.
+if (DEFINED LIBPSATS_BUILD_TYPE)
+	set_target_properties(libpsats::psats PROPERTIES
+		MAP_IMPORTED_CONFIG_DEBUG				${LIBPSATS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_MINSIZEREL			${LIBPSATS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_MINSIZWITHDEBINFO	${LIBPSATS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_RELEASE				${LIBPSATS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_RELWITHDEBINFO		${LIBPSATS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_DEBUGCOVERAGE		${LIBPSATS_BUILD_TYPE}
+	)
+
+	# Do a manual check and issue a better message than the default one.
+	get_property(_libpsats_build_type TARGET libpsats::psats PROPERTY IMPORTED_CONFIGURATIONS)
+	string(TOUPPER ${LIBPSATS_BUILD_TYPE} _uc_libpsats_build_type)
+	if(${_uc_libpsats_build_type} IN_LIST _libpsats_build_type)
+	else()
+		message(FATAL_ERROR "Installed libpsats package does not supports required build type ${LIBPSATS_BUILD_TYPE}.")
+	endif()
+	unset(_libpsats_build_type)
+	unset(_uc_libpsats_build_type)
+endif()
+
+# libpsats can not be used without libts, so add the needed dependency.
+include(${TS_ROOT}/deployments/libts/libts-import.cmake)
+target_link_libraries(libpsats::psats INTERFACE libts::ts)
diff --git a/deployments/libpsats/libpsats.cmake b/deployments/libpsats/libpsats.cmake
new file mode 100644
index 0000000..9ce0039
--- /dev/null
+++ b/deployments/libpsats/libpsats.cmake
@@ -0,0 +1,107 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+#  The base build file shared between deployments of 'libpsats' for different
+#  environments.  libpsats provides an interface for accessing PSA API-s.
+#  Building with each build type results in different postfix for the library.
+#  For details, please refer to deployment.cmake.
+#-------------------------------------------------------------------------------
+
+#-------------------------------------------------------------------------------
+#  Common API version implemented by all libpsats deployments
+#-------------------------------------------------------------------------------
+version_semver_read(FILE "${CMAKE_CURRENT_LIST_DIR}/version.txt"
+					MAJOR _major MINOR _minor PATCH _patch)
+set_target_properties(psats PROPERTIES VERSION "${_major}.${_minor}.${_patch}")
+set_target_properties(psats PROPERTIES SOVERSION "${_major}")
+unset(_major)
+unset(_minor)
+unset(_patch)
+
+add_library(libpsats::psats ALIAS psats)
+
+if (COVERAGE)
+	set(LIBPSATS_BUILD_TYPE "DebugCoverage" CACHE STRING "Build type." FORCE)
+endif()
+
+#-------------------------------------------------------------------------------
+#  Use libts for locating and accessing services. An appropriate version of
+#  libts will be imported for the environment in which service tests are
+#  deployed.
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/deployments/libts/libts-import.cmake)
+target_link_libraries(psats PUBLIC libts::ts)
+
+#-------------------------------------------------------------------------------
+#  Components that are common across all deployments
+#
+#-------------------------------------------------------------------------------
+
+add_components(
+	TARGET "psats"
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"environments/${TS_ENV}"
+		"components/common/utils"
+		"components/common/trace"
+		"components/common/libpsats"
+		"components/common/tlv"
+		"components/service/common/include"
+		"components/service/common/client"
+		"components/service/crypto/include"
+		"components/service/crypto/client/psa"
+		"components/service/attestation/include"
+		"components/service/attestation/client/psa"
+		"components/service/attestation/client/provision"
+		"components/service/secure_storage/include"
+		"components/service/secure_storage/frontend/psa/its"
+		"components/service/secure_storage/frontend/psa/ps"
+		"components/service/secure_storage/backend/secure_storage_client"
+)
+
+#-------------------------------------------------------------------------------
+#  Define public interfaces for library
+#
+#-------------------------------------------------------------------------------
+
+# Enable exporting interface symbols for library public interface
+target_compile_definitions(psats PRIVATE
+	EXPORT_PUBLIC_INTERFACE_LIBPSATS
+	EXPORT_PUBLIC_INTERFACE_PSA_CRYPTO
+	EXPORT_PUBLIC_INTERFACE_PSA_ATTEST
+	EXPORT_PUBLIC_INTERFACE_PSA_ITS
+	EXPORT_PUBLIC_INTERFACE_PSA_PS
+)
+
+#-------------------------------------------------------------------------------
+#  Export the library and the corresponding public interface header files
+#
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/tools/cmake/common/ExportLibrary.cmake REQUIRED)
+
+# Exports library information in preparation for install
+export_library(
+	TARGET "psats"
+	LIB_NAME "libpsats"
+	PKG_CONFIG_FILE "${CMAKE_CURRENT_LIST_DIR}/libpsatsConfig.cmake.in"
+)
+
+install(DIRECTORY "${TS_ROOT}/components/service/crypto/include"
+		DIRECTORY "${TS_ROOT}/components/service/attestation/include"
+		DIRECTORY "${TS_ROOT}/components/service/secure_storage/include"
+		DESTINATION "${TS_ENV}"
+		FILES_MATCHING PATTERN "*.h"
+)
+
+install(FILES "${TS_ROOT}/components/service/common/include/psa/error.h"
+		DESTINATION ${TS_ENV}/include/psa
+)
+
+install(FILES "${TS_ROOT}/components/common/libpsats/libpsats.h"
+		DESTINATION ${TS_ENV}/include
+)
diff --git a/deployments/libpsats/libpsatsConfig.cmake.in b/deployments/libpsats/libpsatsConfig.cmake.in
new file mode 100644
index 0000000..f23ed8d
--- /dev/null
+++ b/deployments/libpsats/libpsatsConfig.cmake.in
@@ -0,0 +1,9 @@
+#
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+@PACKAGE_INIT@
+
+include("${CMAKE_CURRENT_LIST_DIR}/libpsatsTargets.cmake")
diff --git a/deployments/libpsats/linux-pc/CMakeLists.txt b/deployments/libpsats/linux-pc/CMakeLists.txt
new file mode 100644
index 0000000..1d3696b
--- /dev/null
+++ b/deployments/libpsats/linux-pc/CMakeLists.txt
@@ -0,0 +1,44 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
+include(../../deployment.cmake REQUIRED)
+
+#-------------------------------------------------------------------------------
+#  Options and variables
+#-------------------------------------------------------------------------------
+set(BUILD_SHARED_LIBS On CACHE BOOL "Determine if a shared library is being built.")
+if(NOT BUILD_SHARED_LIBS)
+	message(FATAL_ERROR "Building static library is not yet supported. Call cmake with -DBUILD_SHARED_LIBS=1")
+endif()
+
+#-------------------------------------------------------------------------------
+#  The CMakeLists.txt for building the libpsats deployment for arm-linux
+#
+#  Used for building the libpsats library for the arm-linux environment. Used for
+#  locating and accessing services from a Linux userspace client. Service
+#  instances can be located in any supported secure processing environment.
+#-------------------------------------------------------------------------------
+include(${TS_ROOT}/environments/linux-pc/env_shared_lib.cmake)
+project(psats LANGUAGES CXX C)
+
+add_library(psats)
+
+target_include_directories(psats PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
+
+#-------------------------------------------------------------------------------
+#  For user-specific tracing set to TRACE_LEVEL_NONE and implement:
+#  void trace_puts(const char *str)
+#-------------------------------------------------------------------------------
+
+set(TRACE_PREFIX "LIBPSATS" CACHE STRING "Trace prefix")
+set(TRACE_LEVEL "TRACE_LEVEL_DEBUG" CACHE STRING "Trace level")
+#-------------------------------------------------------------------------------
+#  Extend with components that are common across all deployments of
+#  libpsats
+#
+#-------------------------------------------------------------------------------
+include(../libpsats.cmake REQUIRED)
diff --git a/deployments/libpsats/version.txt b/deployments/libpsats/version.txt
new file mode 100644
index 0000000..afaf360
--- /dev/null
+++ b/deployments/libpsats/version.txt
@@ -0,0 +1 @@
+1.0.0
\ No newline at end of file
diff --git a/deployments/libsp/opteesp/CMakeLists.txt b/deployments/libsp/opteesp/CMakeLists.txt
index a690c0c..efbcda7 100644
--- a/deployments/libsp/opteesp/CMakeLists.txt
+++ b/deployments/libsp/opteesp/CMakeLists.txt
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -37,26 +37,7 @@
 		components/common/utils
 )
 
-# Include newlib into the build, but do no add SP executable specific files to libsp.
-# Use a dummy target which will never be built.
-function(get_newlib_compile_flags)
-	# Environment specific files require this variable to be set.
-	# Set it to a dummy value as we are not going to build these anyways.
-	# The namespace of the function will ensure globas setting is not affected.
-	set(SP_FFA_UUID_CANON "00000000-0000-0000-0000-000000000000")
-	set(SP_HEAP_SIZE 4096)
-	add_library(dummy EXCLUDE_FROM_ALL)
-	add_components(TARGET dummy
-		BASE_DIR ${TS_ROOT}
-		COMPONENTS
-			environments/opteesp
-	)
-endfunction()
-
-get_newlib_compile_flags()
-
-# Get libc specific settings from newlib.
-target_link_libraries(sp PUBLIC stdlib::c)
+add_subdirectory(${TS_ROOT}/components/common/libc ${CMAKE_BINARY_DIR}/libc_build)
 
 target_compile_definitions(sp PRIVATE
 	ARM64=1
diff --git a/deployments/libsp/opteesp/version.txt b/deployments/libsp/opteesp/version.txt
index 359a5b9..56fea8a 100644
--- a/deployments/libsp/opteesp/version.txt
+++ b/deployments/libsp/opteesp/version.txt
@@ -1 +1 @@
-2.0.0
\ No newline at end of file
+3.0.0
\ No newline at end of file
diff --git a/deployments/libts/arm-linux/CMakeLists.txt b/deployments/libts/arm-linux/CMakeLists.txt
index 1c190a8..5416656 100644
--- a/deployments/libts/arm-linux/CMakeLists.txt
+++ b/deployments/libts/arm-linux/CMakeLists.txt
@@ -24,6 +24,13 @@
 set(MM_COMM_BUFFER_SIZE "8*4*1024" CACHE STRING "Size of the MM communicate buffer in bytes")
 
 #-------------------------------------------------------------------------------
+#  For user-specific tracing set to TRACE_LEVEL_NONE and implement:
+#  void trace_puts(const char *str)
+#-------------------------------------------------------------------------------
+
+set(TRACE_PREFIX "LIBTS" CACHE STRING "Trace prefix")
+set(TRACE_LEVEL "TRACE_LEVEL_DEBUG" CACHE STRING "Trace level")
+#-------------------------------------------------------------------------------
 #  Components that are specific to deployment in the arm-linux environment.
 #
 #-------------------------------------------------------------------------------
diff --git a/deployments/libts/libts-import.cmake b/deployments/libts/libts-import.cmake
index fd016ca..d0b728d 100644
--- a/deployments/libts/libts-import.cmake
+++ b/deployments/libts/libts-import.cmake
@@ -16,6 +16,10 @@
 version_semver_read(FILE "${CMAKE_CURRENT_LIST_DIR}/version.txt" MAJOR _major MINOR _minor PATCH _patch)
 set(_verstring "${_major}.${_minor}.${_patch}")
 
+if (COVERAGE)
+	set(LIBTS_BUILD_TYPE "DebugCoverage" CACHE STRING "Build type." FORCE)
+endif()
+
 find_package(libts "${_verstring}" QUIET PATHS ${CMAKE_CURRENT_BINARY_DIR}/libts_install/${TS_ENV}/lib/cmake/libts)
 if(NOT libts_FOUND)
 	if (CFG_FORCE_PREBUILT_LIBTS)
@@ -25,15 +29,23 @@
 						   "If you wish to debug the search process pass -DCMAKE_FIND_DEBUG_MODE=ON to cmake.")
 		message(FATAL_ERROR ${_msg})
 	endif()
+	# Set build type, if a specific value is required. This leaves the default value in the hands of the
+	# libts deployment being built.
+	if (DEFINED LIBTS_BUILD_TYPE)
+		set(_libts_build_type_arg "-DCMAKE_BUILD_TYPE=${LIBTS_BUILD_TYPE}")
+	endif()
+
 	# If not successful, build libts as a sub-project.
 	execute_process(COMMAND
 		${CMAKE_COMMAND} -E env "CROSS_COMPILE=${CROSS_COMPILE}"
 		${CMAKE_COMMAND}
+			${_libts_build_type_arg}
 			-S ${TS_ROOT}/deployments/libts/${TS_ENV}
 			-B ${CMAKE_CURRENT_BINARY_DIR}/libts
 		RESULT_VARIABLE
 			_exec_error
 		)
+	unset(_libts_build_type_arg)
 	if (NOT _exec_error EQUAL 0)
 		message(FATAL_ERROR "Configuring libts failed. ${_exec_error}")
 	endif()
@@ -66,3 +78,32 @@
 else()
 	message(STATUS "Using prebuilt libts from ${libts_DIR}")
 endif()
+
+# Cmake will use the same build type of the imported target as used by the main project. If no mapping is configured and
+# the matching build type is not found, cmake will fall back to any build type. Details of the fall back mechanism are not
+# documented.
+# If a mapping is defined, and the imported target does not define the mapped build type, cmake will treat the library
+# as not found.
+#
+# If LIBTS_BUILD_TYPE is set and the main project wants to use a specific build type, configure build type mapping to
+# only allow using the requested build type.
+if (DEFINED LIBTS_BUILD_TYPE)
+	set_target_properties(libts::ts PROPERTIES
+		MAP_IMPORTED_CONFIG_DEBUG				${LIBTS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_MINSIZEREL			${LIBTS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_MINSIZWITHDEBINFO	${LIBTS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_RELEASE				${LIBTS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_RELWITHDEBINFO		${LIBTS_BUILD_TYPE}
+		MAP_IMPORTED_CONFIG_DEBUGCOVERAGE		${LIBTS_BUILD_TYPE}
+	)
+
+	# Do a manual check and issue a better message than the default one.
+	get_property(_libts_build_type TARGET libts::ts PROPERTY IMPORTED_CONFIGURATIONS)
+	string(TOUPPER ${LIBTS_BUILD_TYPE} _uc_libts_build_type)
+	if(${_uc_libts_build_type} IN_LIST _libts_build_type)
+	else()
+		message(FATAL_ERROR "Installed libts package does not supports required build type ${LIBTS_BUILD_TYPE}.")
+	endif()
+	unset(_libts_build_type)
+	unset(_uc_libts_build_type)
+endif()
diff --git a/deployments/libts/libts.cmake b/deployments/libts/libts.cmake
index 0f1a022..af13666 100644
--- a/deployments/libts/libts.cmake
+++ b/deployments/libts/libts.cmake
@@ -24,6 +24,10 @@
 
 add_library(libts::ts ALIAS ts)
 
+if (COVERAGE)
+	set(LIBTS_BUILD_TYPE "DebugCoverage" CACHE STRING "Build type." FORCE)
+endif()
+
 #-------------------------------------------------------------------------------
 #  Components that are common across all deployments
 #
@@ -32,6 +36,8 @@
 	TARGET "ts"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"environments/${TS_ENV}"
+		"components/common/trace"
 		"components/rpc/common/caller"
 		"components/rpc/common/interface"
 		"components/service/locator"
@@ -45,6 +51,7 @@
 
 # Enable exporting interface symbols for library public interface
 target_compile_definitions(ts PRIVATE
+	EXPORT_PUBLIC_INTERFACE_TRACE
 	EXPORT_PUBLIC_INTERFACE_RPC_CALLER
 	EXPORT_PUBLIC_INTERFACE_RPC_SERVICE
 	EXPORT_PUBLIC_INTERFACE_SERVICE_LOCATOR
@@ -59,6 +66,9 @@
 #-------------------------------------------------------------------------------
 include(${TS_ROOT}/tools/cmake/common/ExportLibrary.cmake REQUIRED)
 
+set_property(TARGET "ts" APPEND PROPERTY
+			PUBLIC_HEADER "${TS_ROOT}/components/common/trace/include/trace.h")
+
 # Exports library information in preparation for install
 export_library(
 	TARGET "ts"
diff --git a/deployments/libts/linux-pc/CMakeLists.txt b/deployments/libts/linux-pc/CMakeLists.txt
index 24b89d4..c9f84be 100644
--- a/deployments/libts/linux-pc/CMakeLists.txt
+++ b/deployments/libts/linux-pc/CMakeLists.txt
@@ -22,6 +22,13 @@
 target_include_directories(ts PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
 #-------------------------------------------------------------------------------
+#  For user-specific tracing set to TRACE_LEVEL_NONE and implement:
+#  void trace_puts(const char *str)
+#-------------------------------------------------------------------------------
+
+set(TRACE_PREFIX "LIBTS" CACHE STRING "Trace prefix")
+set(TRACE_LEVEL "TRACE_LEVEL_DEBUG" CACHE STRING "Trace level")
+#-------------------------------------------------------------------------------
 #  External project source-level dependencies
 #
 #-------------------------------------------------------------------------------
@@ -63,8 +70,8 @@
 		"components/common/uuid"
 		"components/common/endian"
 		"components/common/utils"
-		"components/common/trace"
 		"components/common/crc32"
+		"components/common/mbedtls"
 		"components/config/ramstore"
 		"components/service/common/include"
 		"components/service/common/client"
@@ -160,14 +167,6 @@
 )
 
 #-------------------------------------------------------------------------------
-#  Configure added components
-#
-#-------------------------------------------------------------------------------
-# Force trace level to TRACE_LEVEL_NONE to disable trace messages. This is
-# needed till proper trace enablement for the linux-pc environment is done.
-target_compile_definitions(ts PUBLIC TRACE_LEVEL=0)
-
-#-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  libts
 #
@@ -185,7 +184,7 @@
 protobuf_generate_all(TGT "ts" NAMESPACE "protobuf" BASE_DIR "${TS_ROOT}/protocols")
 
 # MbedTLS
-set(MBEDTLS_USER_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/libmbedx509.h"
+set(MBEDTLS_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/crypto_provider_x509.h"
 	CACHE STRING "Configuration file for Mbed TLS" FORCE)
 include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
 target_link_libraries(ts PRIVATE MbedTLS::mbedcrypto)
@@ -193,7 +192,7 @@
 
 # Pass the location of the mbedtls config file to C preprocessor.
 target_compile_definitions(ts PRIVATE
-		MBEDTLS_USER_CONFIG_FILE="${MBEDTLS_USER_CONFIG_FILE}"
+		MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}"
 )
 
 # Qcbor
diff --git a/deployments/logging/config/default-opteesp/CMakeLists.txt b/deployments/logging/config/default-opteesp/CMakeLists.txt
index cd46a15..2ca7186 100644
--- a/deployments/logging/config/default-opteesp/CMakeLists.txt
+++ b/deployments/logging/config/default-opteesp/CMakeLists.txt
@@ -74,13 +74,8 @@
 if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
-install(TARGETS logging
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
-			RUNTIME DESTINATION ${TS_ENV}/bin
-		)
 
 install(TARGETS logging
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/logging/config/default-opteesp/default_logging.dts.in b/deployments/logging/config/default-opteesp/default_logging.dts.in
index ca21f8f..6013d29 100644
--- a/deployments/logging/config/default-opteesp/default_logging.dts.in
+++ b/deployments/logging/config/default-opteesp/default_logging.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "Logging";
 	execution-ctx-count = <1>;
diff --git a/deployments/logging/config/default-sp/CMakeLists.txt b/deployments/logging/config/default-sp/CMakeLists.txt
index 0f4d7a2..99574da 100644
--- a/deployments/logging/config/default-sp/CMakeLists.txt
+++ b/deployments/logging/config/default-sp/CMakeLists.txt
@@ -85,13 +85,8 @@
 if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
-install(TARGETS logging
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
-			RUNTIME DESTINATION ${TS_ENV}/bin
-		)
 
 install(TARGETS logging
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/logging/config/default-sp/default_logging.dts.in b/deployments/logging/config/default-sp/default_logging.dts.in
index 1d73164..0cc45c3 100644
--- a/deployments/logging/config/default-sp/default_logging.dts.in
+++ b/deployments/logging/config/default-sp/default_logging.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "Logging";
 	execution-ctx-count = <1>;
diff --git a/deployments/logging/env/commonsp/logging_sp.c b/deployments/logging/env/commonsp/logging_sp.c
index af81d2c..03bbcfb 100644
--- a/deployments/logging/env/commonsp/logging_sp.c
+++ b/deployments/logging/env/commonsp/logging_sp.c
@@ -101,6 +101,22 @@
 	(void)interrupt_id;
 }
 
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
 static bool sp_init(uint16_t *own_id)
 {
 	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
diff --git a/deployments/newlib/opteesp/CMakeLists.txt b/deployments/newlib/opteesp/CMakeLists.txt
deleted file mode 100644
index 5363d84..0000000
--- a/deployments/newlib/opteesp/CMakeLists.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-cmake_minimum_required(VERSION 3.14)
-include(../../deployment.cmake REQUIRED)
-
-#-------------------------------------------------------------------------------
-#  The CMakeLists.txt for building the newlib deployment for opteesp
-#
-#  Can be used to build the newlib library, which can be used to build SPs.
-#-------------------------------------------------------------------------------
-include(${TS_ROOT}/environments/opteesp/env.cmake)
-
-project(newlib C)
-
-# This is a dummy library not intended to be compiled ever.
-add_library(dummy EXCLUDE_FROM_ALL)
-set(TGT dummy)
-# Build newlib as an external component.
-include(${TS_ROOT}/external/newlib/newlib.cmake)
-
-######################################## install
-if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
-	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
-endif()
-
-# export the newlib install content from CMAKE_BINARY_DIR.
-install(DIRECTORY ${NEWLIB_INSTALL_DIR}/ DESTINATION ${TS_ENV}/newlib)
diff --git a/deployments/platform-inspect/platform-inspect.cmake b/deployments/platform-inspect/platform-inspect.cmake
index aa3c523..f5589ff 100644
--- a/deployments/platform-inspect/platform-inspect.cmake
+++ b/deployments/platform-inspect/platform-inspect.cmake
@@ -11,12 +11,16 @@
 #-------------------------------------------------------------------------------
 
 #-------------------------------------------------------------------------------
-#  Use libts for locating and accessing trusted services. An appropriate version
-#  of libts will be imported for the environment in which platform-inspect is
-#  built.
+#  Use libpsats for locating PSA services. An appropriate version of
+#  libpsats will be imported for the environment.
 #-------------------------------------------------------------------------------
-include(${TS_ROOT}/deployments/libts/libts-import.cmake)
-target_link_libraries(platform-inspect PRIVATE libts::ts)
+if (COVERAGE)
+	set(LIBPSATS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libpsats build type" FORCE)
+	set(LIBTS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libts build type" FORCE)
+endif()
+
+include(${TS_ROOT}/deployments/libpsats/libpsats-import.cmake)
+target_link_libraries(platform-inspect PRIVATE libpsats::psats)
 
 #-------------------------------------------------------------------------------
 #  Components that are common across all deployments
@@ -29,11 +33,6 @@
 		"components/app/platform-inspect"
 		"components/common/tlv"
 		"components/common/cbor_dump"
-		"components/service/common/client"
-		"components/service/common/include"
-		"components/service/attestation/include"
-		"components/service/attestation/client/psa"
-		"components/service/attestation/client/provision"
 		"components/service/attestation/reporter/dump/raw"
 		"components/service/attestation/reporter/dump/pretty"
 )
@@ -44,7 +43,7 @@
 #-------------------------------------------------------------------------------
 
 # MbedTLS provides libmbedcrypto
-set(MBEDTLS_USER_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/crypto_posix.h"
+set(MBEDTLS_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/crypto_posix.h"
 	CACHE STRING "Configuration file for mbedcrypto")
 include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
 target_link_libraries(platform-inspect PRIVATE MbedTLS::mbedcrypto)
diff --git a/deployments/protected-storage/config/default-opteesp/CMakeLists.txt b/deployments/protected-storage/config/default-opteesp/CMakeLists.txt
index bc52897..4038d7d 100644
--- a/deployments/protected-storage/config/default-opteesp/CMakeLists.txt
+++ b/deployments/protected-storage/config/default-opteesp/CMakeLists.txt
@@ -73,7 +73,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS protected-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/protected-storage/config/default-opteesp/default_protected-storage.dts.in b/deployments/protected-storage/config/default-opteesp/default_protected-storage.dts.in
index 2bc74a4..c8d86d6 100644
--- a/deployments/protected-storage/config/default-opteesp/default_protected-storage.dts.in
+++ b/deployments/protected-storage/config/default-opteesp/default_protected-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "PS";
 	execution-ctx-count = <1>;
diff --git a/deployments/protected-storage/config/default-sp/CMakeLists.txt b/deployments/protected-storage/config/default-sp/CMakeLists.txt
index 9f6f156..47a6675 100644
--- a/deployments/protected-storage/config/default-sp/CMakeLists.txt
+++ b/deployments/protected-storage/config/default-sp/CMakeLists.txt
@@ -78,7 +78,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS protected-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/protected-storage/config/default-sp/default_protected-storage.dts.in b/deployments/protected-storage/config/default-sp/default_protected-storage.dts.in
index 79c001f..971a3b5 100644
--- a/deployments/protected-storage/config/default-sp/default_protected-storage.dts.in
+++ b/deployments/protected-storage/config/default-sp/default_protected-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "PS";
 	execution-ctx-count = <1>;
diff --git a/deployments/protected-storage/config/shared-flash-opteesp/CMakeLists.txt b/deployments/protected-storage/config/shared-flash-opteesp/CMakeLists.txt
index a737c37..9d6aabc 100644
--- a/deployments/protected-storage/config/shared-flash-opteesp/CMakeLists.txt
+++ b/deployments/protected-storage/config/shared-flash-opteesp/CMakeLists.txt
@@ -65,7 +65,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS protected-storage
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/protected-storage/config/shared-flash-opteesp/default_protected-storage.dts.in b/deployments/protected-storage/config/shared-flash-opteesp/default_protected-storage.dts.in
index 2bc74a4..c8d86d6 100644
--- a/deployments/protected-storage/config/shared-flash-opteesp/default_protected-storage.dts.in
+++ b/deployments/protected-storage/config/shared-flash-opteesp/default_protected-storage.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "PS";
 	execution-ctx-count = <1>;
diff --git a/deployments/protected-storage/env/commonsp/ps_sp.c b/deployments/protected-storage/env/commonsp/ps_sp.c
index c43bccb..f88477b 100644
--- a/deployments/protected-storage/env/commonsp/ps_sp.c
+++ b/deployments/protected-storage/env/commonsp/ps_sp.c
@@ -110,3 +110,19 @@
 {
 	(void)interrupt_id;
 }
+
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
diff --git a/deployments/psa-api-test/arch_test_runner.c b/deployments/psa-api-test/arch_test_runner.c
index 8fd3dac..b5cd69c 100644
--- a/deployments/psa-api-test/arch_test_runner.c
+++ b/deployments/psa-api-test/arch_test_runner.c
@@ -5,163 +5,180 @@
  */
 
 #include <ctype.h>
-#include <stdint.h>
+#include <rpc_caller.h>
 #include <stdbool.h>
+#include <stdint.h>
 #include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
-#include "service_under_test.h"
+#include <string.h>
 
-#define TEST_ID_OFFSET      (5)
+#include "psa_api_test_common.h"
+#include "trace.h"
+
+#define TEST_ID_OFFSET	    (5)
 #define TEST_POSTFIX_OFFSET (8)
 #define TEST_ENTRY_LENGTH   (9)
 
-
 int32_t val_entry(void);
-extern size_t val_get_test_list(uint32_t *test_id_list, size_t size);
-extern void pal_set_custom_test_list(char *custom_test_list);
+size_t val_get_test_list(uint32_t *test_id_list, size_t size);
+void pal_set_custom_test_list(char *custom_test_list);
 
 /* Returns whether option_switch is in the argv list and provide its index in the array */
 static bool option_selected(const char *option_switch, int argc, char *argv[], int *index)
 {
-    bool selected = false;
-    *index = 0;
+	bool selected = false;
+	*index = 0;
 
-    for (int i = 1; (i < argc) && !selected; ++i) {
+	for (int i = 1; (i < argc) && !selected; ++i) {
+		selected = (strcmp(argv[i], option_switch) == 0);
+		*index = i;
+	}
 
-        selected = (strcmp(argv[i], option_switch) == 0);
-        *index = i;
-    }
-
-    return selected;
+	return selected;
 }
 
 /* Print the supported command line arguments */
 static void print_help(void)
 {
-    printf("Supported command line arguments:\n\n");
-    printf("\t -l: Print list of tests.\n");
-    printf("\t -t <test_list>: Run only the listed tests (e.g: test_201;test_202;). test_list = ^(test_[0-9]{3};)+ \n");
-    printf("\t -v: Verbose mode.\n");
-    printf("\t -h: Print this help message.\n");
-    printf("\n");
+	EMSG("Supported command line arguments:\n");
+	EMSG("\t -l: Print list of tests.");
+	EMSG("\t -t <test_list>: Run only the listed tests (e.g: test_201;test_202;). test_list = ^(test_[0-9]{3};)+");
+	EMSG("\t -c: <service name>: Crypto service name");
+	EMSG("\t -a: <service name>: Initial attestation service name");
+	EMSG("\t -p: <service name>: Protected Storage service name");
+	EMSG("\t -i: <service name>: Internal Trusted Storage service name");
+	EMSG("\t -v: Verbose mode.");
+	EMSG("\t -h: Print this help message.\n");
 }
 
 /* Prints the list of selectable psa-api tests */
 static void print_psa_api_tests(void)
 {
-    /* Request the number of tests to find out the size of the area needed to store the test ID-s. */
-    size_t n_test = val_get_test_list(NULL, 0);
+	/*
+	 * Request the number of tests to find out the size
+	 * of the area needed to store the test ID-s.
+	 */
+	size_t n_test = val_get_test_list(NULL, 0);
 
-    uint32_t *test_id_list = (uint32_t *)calloc(n_test, sizeof(uint32_t));
+	uint32_t *test_id_list = (uint32_t *)calloc(n_test, sizeof(uint32_t));
 
-    if (test_id_list) {
-        n_test = val_get_test_list(test_id_list, n_test);
+	if (test_id_list) {
+		n_test = val_get_test_list(test_id_list, n_test);
 
-        printf("Available psa-api tests:\n");
-        for (int i = 0; i < n_test; i++) {
-                printf("\t test_%d;\n", test_id_list[i]);
-        }
+		EMSG("Available psa-api tests:");
+		for (int i = 0; i < n_test; i++)
+			EMSG("\t test_%d;", test_id_list[i]);
 
-        free(test_id_list);
-    }
-    else {
-        printf("Could not allocate enough memory to store the list of tests\n");
-    }
+		free(test_id_list);
+	} else {
+		EMSG("Could not allocate enough memory to store the list of tests");
+	}
 }
 
 /* Check if the received test list string is formatted as expected */
-static bool is_test_list_wrong(char* test_list)
+static bool is_test_list_wrong(char *test_list)
 {
-    size_t len = strlen(test_list);
+	size_t len = strlen(test_list);
 
-    for (unsigned i = 0; i < len; i += TEST_ENTRY_LENGTH) {
+	for (unsigned int i = 0; i < len; i += TEST_ENTRY_LENGTH) {
+		/* Report error when the test entry is not properly finished */
+		if (i + TEST_ENTRY_LENGTH > len) {
+			EMSG("Expecting \"test_xxx;\" test entry at the %dth character, got \"%s\" instead.",
+			     i, &test_list[i]);
+			return true;
+		}
 
-        /* Report error when the test entry is not properly finished */
-        if (i + TEST_ENTRY_LENGTH > len) {
-            printf("Expecting \"test_xxx;\" test entry at the %dth character, got \"%s\" instead.\n", i, &test_list[i]);
-            return true;
-        }
+		/* Report error at incorrect test entry prefix */
+		if (memcmp(&test_list[i], "test_", TEST_ID_OFFSET)) {
+			EMSG("Expecting \"test_\" at the %dth character, got \"%.5s\" instead.", i,
+			     &test_list[i]);
+			return true;
+		}
 
-        /* Report error at incorrect test entry prefix */
-        if (memcmp(&test_list[i], "test_", TEST_ID_OFFSET)) {
-            printf("Expecting \"test_\" at the %dth character, got \"%.5s\" instead.\n", i, &test_list[i]);
-            return true;
-        }
+		/* Report error if the test ID is incorrect */
+		if (!(isdigit(test_list[i + TEST_ID_OFFSET]) &&
+		      isdigit(test_list[i + TEST_ID_OFFSET + 1]) &&
+		      isdigit(test_list[i + TEST_ID_OFFSET + 2]))) {
+			EMSG("Expecting three digits at %dth character, got \"%.3s\" instead.",
+			     i + TEST_ID_OFFSET, &test_list[i + TEST_ID_OFFSET]);
+			return true;
+		}
 
-        /* Report error if the test ID is incorrect */
-        if (!(isdigit(test_list[i + TEST_ID_OFFSET]) &&
-              isdigit(test_list[i + TEST_ID_OFFSET + 1]) &&
-              isdigit(test_list[i + TEST_ID_OFFSET + 2]))) {
-            printf("Expecting three digits at the %dth character, got \"%.3s\" instead.\n",
-                i + TEST_ID_OFFSET,
-                &test_list[i + TEST_ID_OFFSET]);
-            return true;
-        }
+		/* Report error at incorrect test entry postfix */
+		if (test_list[i + TEST_POSTFIX_OFFSET] != ';') {
+			EMSG("Expecting ; at the %dth character, got \"%.1s\" instead.",
+			     i + TEST_POSTFIX_OFFSET, &test_list[i + TEST_POSTFIX_OFFSET]);
+			return true;
+		}
+	}
 
-        /* Report error at incorrect test entry postfix */
-        if (test_list[i + TEST_POSTFIX_OFFSET] != ';') {
-            printf("Expecting ; at the %dth character, got \"%.1s\" instead.\n",
-                i + TEST_POSTFIX_OFFSET,
-                &test_list[i + TEST_POSTFIX_OFFSET]);
-            return true;
-        }
-    }
-
-    return false;
+	return false;
 }
 
 /* Entry point */
 int main(int argc, char *argv[])
 {
-    int rval = -1;
-    int option_index = 0;
+	int rval = -1;
+	int option_index = 0;
+	char *service_name_crypto = NULL;
+	char *service_name_iat = NULL;
+	char *service_name_ps = NULL;
+	char *service_name_its = NULL;
 
-     /* Print available tests */
-    if (option_selected("-l", argc, argv, &option_index)) {
-        print_psa_api_tests();
-        return 0;
-    }
+	/* Print available tests */
+	if (option_selected("-l", argc, argv, &option_index)) {
+		print_psa_api_tests();
+		return 0;
+	}
 
-    /* Create custom test list */
-    if (option_selected("-t", argc, argv, &option_index)) {
-        /* Avoid overindexing of argv and detect if the option is followed by another option */
-        char *test_list_values = argv[option_index + 1];
-        if ((option_index >= argc) || (test_list_values[0] == '-')) {
-            printf("Testlist string is expected after -t argument!\n");
-            return -1;
-        }
+	/* Create custom test list */
+	if (option_selected("-t", argc, argv, &option_index)) {
+		/*
+		 * Avoid overindexing of argv and detect if the
+		 * option is followed by another option
+		 */
+		char *test_list_values = argv[option_index + 1];
 
-        if (is_test_list_wrong(test_list_values)) {
-            printf("Testlist string is not valid!\n");
-            print_psa_api_tests();
-            return -1;
-        }
+		if ((option_index >= argc) || (test_list_values[0] == '-')) {
+			EMSG("Testlist string is expected after -t argument!");
+			return -1;
+		}
 
-        /* Filter tests */
-        pal_set_custom_test_list(test_list_values);
-    }
+		if (is_test_list_wrong(test_list_values)) {
+			EMSG("Testlist string is not valid!");
+			print_psa_api_tests();
+			return -1;
+		}
 
-    /* Print help */
-    if (option_selected("-h", argc, argv, &option_index)) {
-        print_help();
-        return 0;
-    }
+		/* Filter tests */
+		pal_set_custom_test_list(test_list_values);
+	}
 
-    /* Locate service under test */
-    rval = locate_service_under_test();
+	/* Print help */
+	if (option_selected("-h", argc, argv, &option_index)) {
+		print_help();
+		return 0;
+	}
 
-    /* Run tests */
-    if (!rval) {
+	/* Process optional service names */
+	if (option_selected("-c", argc, argv, &option_index))
+		service_name_crypto = argv[option_index + 1];
 
-        rval = val_entry();
+	if (option_selected("-a", argc, argv, &option_index))
+		service_name_iat = argv[option_index + 1];
 
-        relinquish_service_under_test();
-    }
-    else {
+	if (option_selected("-p", argc, argv, &option_index))
+		service_name_ps = argv[option_index + 1];
 
-        printf("Failed to locate service under test.  Error code: %d\n", rval);
-    }
+	if (option_selected("-i", argc, argv, &option_index))
+		service_name_its = argv[option_index + 1];
 
-    return rval;
+	rval = test_setup(service_name_crypto, service_name_iat, service_name_ps, service_name_its);
+
+	if (!rval)
+		rval = val_entry();
+
+	test_teardown();
+
+	return rval;
 }
diff --git a/deployments/psa-api-test/crypto/arm-linux/CMakeLists.txt b/deployments/psa-api-test/crypto/arm-linux/CMakeLists.txt
index 2ef6303..8e72bc4 100644
--- a/deployments/psa-api-test/crypto/arm-linux/CMakeLists.txt
+++ b/deployments/psa-api-test/crypto/arm-linux/CMakeLists.txt
@@ -18,6 +18,14 @@
 add_executable(${PROJECT_NAME})
 target_include_directories(${PROJECT_NAME} PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
+set(TRACE_PREFIX "PSACRYPTO" CACHE STRING "Trace prefix")
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/common/trace"
+		"environments/arm-linux"
+)
+
 #-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  psa-api-test/crypto
diff --git a/deployments/psa-api-test/crypto/crypto-api-test.cmake b/deployments/psa-api-test/crypto/crypto-api-test.cmake
index 9cc97e3..8d4f5e1 100644
--- a/deployments/psa-api-test/crypto/crypto-api-test.cmake
+++ b/deployments/psa-api-test/crypto/crypto-api-test.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -29,16 +29,15 @@
 #  Crypto specific components
 #
 #-------------------------------------------------------------------------------
-add_components(
-	TARGET "${PROJECT_NAME}"
-	BASE_DIR ${TS_ROOT}
-	COMPONENTS
-		"components/service/crypto/include"
-		"components/service/crypto/client/psa"
+target_sources(${PROJECT_NAME} PRIVATE
+	${TS_ROOT}/deployments/psa-api-test/crypto/crypto.c
 )
 
-target_sources(${PROJECT_NAME} PRIVATE
-	${TS_ROOT}/deployments/psa-api-test/crypto/crypto_locator.c
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/service/common/include"
+		"components/service/crypto/include"
 )
 
 #-------------------------------------------------------------------------------
diff --git a/deployments/psa-api-test/crypto/crypto.c b/deployments/psa-api-test/crypto/crypto.c
new file mode 100644
index 0000000..612012d
--- /dev/null
+++ b/deployments/psa-api-test/crypto/crypto.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../psa_api_test_common.h"
+#include "libpsats.h"
+#include "trace.h"
+
+psa_status_t test_setup(const char *service_name_crypto, const char *service_name_iat,
+			const char *service_name_ps, const char *service_name_its)
+{
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+
+	if (!service_name_crypto)
+		service_name_crypto = "sn:trustedfirmware.org:crypto:0";
+
+	psa_status = libpsats_init_crypto_context(service_name_crypto);
+	if (psa_status) {
+		EMSG("libpsats_init_crypto_context failed: %d\n", psa_status);
+		return psa_status;
+	}
+
+	psa_status = psa_crypto_init();
+	if (psa_status) {
+		EMSG("psa_crypto_init failed: %d\n", psa_status);
+		return psa_status;
+	}
+
+	return PSA_SUCCESS;
+}
+
+void test_teardown(void)
+{
+	libpsats_deinit_crypto_context();
+}
diff --git a/deployments/psa-api-test/crypto/crypto_locator.c b/deployments/psa-api-test/crypto/crypto_locator.c
deleted file mode 100644
index c57a501..0000000
--- a/deployments/psa-api-test/crypto/crypto_locator.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-#include <service_locator.h>
-#include <service/crypto/client/psa/psa_crypto_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include "../service_under_test.h"
-
-/* RPC context */
-static struct rpc_caller_session *session = NULL;
-static struct service_context *attestation_service_context = NULL;
-
-int locate_service_under_test(void)
-{
-	int status = -1;
-
-	if (!session && !attestation_service_context) {
-
-		service_locator_init();
-
-		attestation_service_context =
-			service_locator_query("sn:trustedfirmware.org:crypto:0");
-
-		if (attestation_service_context) {
-
-			session = service_context_open(attestation_service_context);
-
-			if (session) {
-
-				psa_crypto_client_init(session);
-
-				status = 0;
-			}
-			else {
-
-				status = -1;
-				relinquish_service_under_test();
-			}
-		}
-	}
-
-	return status;
-}
-
-int relinquish_service_under_test(void)
-{
-	psa_crypto_client_deinit();
-
-	if (attestation_service_context && session) {
-
-		service_context_close(attestation_service_context, session);
-		session = NULL;
-	}
-
-	if (attestation_service_context) {
-
-		service_context_relinquish(attestation_service_context);
-		attestation_service_context = NULL;
-	}
-
-	return 0;
-}
diff --git a/deployments/psa-api-test/crypto/linux-pc/CMakeLists.txt b/deployments/psa-api-test/crypto/linux-pc/CMakeLists.txt
index b99604a..d9ad385 100644
--- a/deployments/psa-api-test/crypto/linux-pc/CMakeLists.txt
+++ b/deployments/psa-api-test/crypto/linux-pc/CMakeLists.txt
@@ -20,6 +20,12 @@
 add_executable(${PROJECT_NAME})
 target_include_directories(${PROJECT_NAME} PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
+set(TRACE_PREFIX "PSACRYPTO" CACHE STRING "Trace prefix")
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS "environments/linux-pc"
+)
+
 #-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  psa-api-test/crypto
diff --git a/deployments/psa-api-test/initial_attestation/arm-linux/CMakeLists.txt b/deployments/psa-api-test/initial_attestation/arm-linux/CMakeLists.txt
index da8e185..fa75297 100644
--- a/deployments/psa-api-test/initial_attestation/arm-linux/CMakeLists.txt
+++ b/deployments/psa-api-test/initial_attestation/arm-linux/CMakeLists.txt
@@ -18,6 +18,14 @@
 add_executable(${PROJECT_NAME})
 target_include_directories(${PROJECT_NAME} PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
+set(TRACE_PREFIX "PSAIAT" CACHE STRING "Trace prefix")
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/common/trace"
+		"environments/arm-linux"
+)
+
 #-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  psa-api-test/initial_attestation
diff --git a/deployments/psa-api-test/initial_attestation/iat-api-test.cmake b/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
index 4d1d2b1..807faf6 100644
--- a/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
+++ b/deployments/psa-api-test/initial_attestation/iat-api-test.cmake
@@ -28,30 +28,18 @@
 #  Attestation specific components.
 #
 #-------------------------------------------------------------------------------
-add_components(
-	TARGET "${PROJECT_NAME}"
+target_sources(${PROJECT_NAME} PRIVATE
+	${TS_ROOT}/deployments/psa-api-test/initial_attestation/iat.c
+)
+
+add_components(TARGET ${PROJECT_NAME}
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"components/service/common/include"
 		"components/service/attestation/include"
-		"components/service/attestation/client/psa"
-		"components/service/attestation/client/provision"
+		"components/service/crypto/include"
 )
 
-target_sources(${PROJECT_NAME} PRIVATE
-	${TS_ROOT}/deployments/psa-api-test/initial_attestation/iat_locator.c
-)
-
-#-------------------------------------------------------------------------------
-#  Add external components used specifically for attestation tests
-#
-#-------------------------------------------------------------------------------
-
-# MbedTLS used for token verification
-set(MBEDTLS_USER_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/crypto_posix.h"
-	CACHE STRING "Configuration file for mbedcrypto")
-include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
-target_link_libraries(${PROJECT_NAME} PRIVATE MbedTLS::mbedcrypto)
-
 # Use Mbed TLS to provide the psa crypto api interface files
 set(PSA_CRYPTO_API_INCLUDE ${MBEDTLS_PUBLIC_INCLUDE_PATH})
 
diff --git a/deployments/psa-api-test/initial_attestation/iat.c b/deployments/psa-api-test/initial_attestation/iat.c
new file mode 100644
index 0000000..438bb58
--- /dev/null
+++ b/deployments/psa-api-test/initial_attestation/iat.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../psa_api_test_common.h"
+#include "libpsats.h"
+#include "trace.h"
+
+psa_status_t test_setup(const char *service_name_crypto, const char *service_name_iat,
+			const char *service_name_ps, const char *service_name_its)
+{
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+
+	if (!service_name_crypto)
+		service_name_crypto = "sn:trustedfirmware.org:crypto:0";
+
+	if (!service_name_iat)
+		service_name_iat = "sn:trustedfirmware.org:attestation:0";
+
+	psa_status = libpsats_init_crypto_context(service_name_crypto);
+	if (psa_status) {
+		EMSG("libpsats_init_crypto_context failed: %d\n", psa_status);
+		return psa_status;
+	}
+
+	psa_status = libpsats_init_attestation_context(service_name_iat);
+	if (psa_status) {
+		EMSG("libpsats_init_attestation_context failed: %d\n", psa_status);
+		return psa_status;
+	}
+
+	psa_status = psa_crypto_init();
+	if (psa_status) {
+		EMSG("psa_crypto_init failed: %d\n", psa_status);
+		return psa_status;
+	}
+
+	return PSA_SUCCESS;
+}
+
+void test_teardown(void)
+{
+	libpsats_deinit_crypto_context();
+	libpsats_deinit_attestation_context();
+}
diff --git a/deployments/psa-api-test/initial_attestation/iat_locator.c b/deployments/psa-api-test/initial_attestation/iat_locator.c
deleted file mode 100644
index 1852fea..0000000
--- a/deployments/psa-api-test/initial_attestation/iat_locator.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-#include <psa/crypto.h>
-#include <service_locator.h>
-#include <service/attestation/client/psa/iat_client.h>
-#include <service/attestation/client/provision/attest_provision_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include "../service_under_test.h"
-
-/* RPC context */
-static struct rpc_caller_session *session = NULL;
-static struct service_context *attestation_service_context = NULL;
-
-int locate_service_under_test(void)
-{
-	int status = -1;
-
-	/* Attestation tests depend on PSA crypto so ensure library is initialised */
-	psa_status_t psa_status = psa_crypto_init();
-
-	if ((psa_status == PSA_SUCCESS) && !session && !attestation_service_context) {
-
-		service_locator_init();
-
-		attestation_service_context =
-			service_locator_query("sn:trustedfirmware.org:attestation:0");
-
-		if (attestation_service_context) {
-
-			session = service_context_open(attestation_service_context);
-
-			if (session) {
-
-				psa_iat_client_init(session);
-				attest_provision_client_init(session);
-
-				status = 0;
-			}
-			else {
-
-				status = -1;
-				relinquish_service_under_test();
-			}
-		}
-	}
-
-	return status;
-}
-
-int relinquish_service_under_test(void)
-{
-	psa_iat_client_deinit();
-	attest_provision_client_deinit();
-
-	if (attestation_service_context && session) {
-
-		service_context_close(attestation_service_context, session);
-		session = NULL;
-	}
-
-	if (attestation_service_context) {
-
-		service_context_relinquish(attestation_service_context);
-		attestation_service_context = NULL;
-	}
-
-	return 0;
-}
diff --git a/deployments/psa-api-test/initial_attestation/linux-pc/CMakeLists.txt b/deployments/psa-api-test/initial_attestation/linux-pc/CMakeLists.txt
index b7e7a76..7c13eef 100644
--- a/deployments/psa-api-test/initial_attestation/linux-pc/CMakeLists.txt
+++ b/deployments/psa-api-test/initial_attestation/linux-pc/CMakeLists.txt
@@ -19,6 +19,12 @@
 add_executable(${PROJECT_NAME})
 target_include_directories(${PROJECT_NAME} PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
+set(TRACE_PREFIX "PSAIAT" CACHE STRING "Trace prefix")
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS "environments/linux-pc"
+)
+
 #-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  psa-api-test/initial_attestation
diff --git a/deployments/psa-api-test/internal_trusted_storage/arm-linux/CMakeLists.txt b/deployments/psa-api-test/internal_trusted_storage/arm-linux/CMakeLists.txt
index 5ccd665..80f6c8e 100644
--- a/deployments/psa-api-test/internal_trusted_storage/arm-linux/CMakeLists.txt
+++ b/deployments/psa-api-test/internal_trusted_storage/arm-linux/CMakeLists.txt
@@ -18,6 +18,14 @@
 add_executable(${PROJECT_NAME})
 target_include_directories(${PROJECT_NAME} PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
+set(TRACE_PREFIX "PSAITS" CACHE STRING "Trace prefix")
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/common/trace"
+		"environments/arm-linux"
+)
+
 #-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  psa-api-test/internal_trusted_storage
diff --git a/deployments/psa-api-test/internal_trusted_storage/its-api-test.cmake b/deployments/psa-api-test/internal_trusted_storage/its-api-test.cmake
index d373e19..f23faa9 100644
--- a/deployments/psa-api-test/internal_trusted_storage/its-api-test.cmake
+++ b/deployments/psa-api-test/internal_trusted_storage/its-api-test.cmake
@@ -22,17 +22,15 @@
 #  Internal trusted storage specific components
 #
 #-------------------------------------------------------------------------------
-add_components(
-	TARGET "${PROJECT_NAME}"
-	BASE_DIR ${TS_ROOT}
-	COMPONENTS
-		"components/service/secure_storage/include"
-		"components/service/secure_storage/frontend/psa/its"
-		"components/service/secure_storage/backend/secure_storage_client"
+target_sources(${PROJECT_NAME} PRIVATE
+	${TS_ROOT}/deployments/psa-api-test/internal_trusted_storage/its.c
 )
 
-target_sources(${PROJECT_NAME} PRIVATE
-	${TS_ROOT}/deployments/psa-api-test/internal_trusted_storage/its_locator.c
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/service/common/include"
+		"components/service/secure_storage/include"
 )
 
 #-------------------------------------------------------------------------------
diff --git a/deployments/psa-api-test/internal_trusted_storage/its.c b/deployments/psa-api-test/internal_trusted_storage/its.c
new file mode 100644
index 0000000..38b3d58
--- /dev/null
+++ b/deployments/psa-api-test/internal_trusted_storage/its.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../psa_api_test_common.h"
+#include "libpsats.h"
+#include "trace.h"
+
+psa_status_t test_setup(const char *service_name_crypto, const char *service_name_iat,
+			const char *service_name_ps, const char *service_name_its)
+{
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+
+	if (!service_name_its)
+		service_name_its = "sn:trustedfirmware.org:internal-trusted-storage:0";
+
+	psa_status = libpsats_init_its_context(service_name_its);
+	if (psa_status) {
+		EMSG("libpsats_init_its_context failed: %d\n", psa_status);
+		return psa_status;
+	}
+
+	return psa_status;
+}
+
+void test_teardown(void)
+{
+	libpsats_deinit_its_context();
+}
diff --git a/deployments/psa-api-test/internal_trusted_storage/its_locator.c b/deployments/psa-api-test/internal_trusted_storage/its_locator.c
deleted file mode 100644
index 7119d21..0000000
--- a/deployments/psa-api-test/internal_trusted_storage/its_locator.c
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-#include <service_locator.h>
-#include <service/secure_storage/frontend/psa/its/its_frontend.h>
-#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include "../service_under_test.h"
-
-/* RPC context */
-static struct rpc_caller_session *session = NULL;
-static struct service_context *ps_service_context = NULL;
-static struct secure_storage_client storage_client;
-
-int locate_service_under_test(void)
-{
-	int status = -1;
-
-	service_locator_init();
-
-	if (!session && !ps_service_context) {
-
-		ps_service_context =
-			service_locator_query("sn:trustedfirmware.org:internal-trusted-storage:0");
-
-		if (ps_service_context) {
-
-			session =
-				service_context_open(ps_service_context);
-
-			if (session) {
-
-				struct storage_backend *storage_backend = NULL;
-				status = -1;
-
-				storage_backend = secure_storage_client_init(&storage_client, session);
-
-				if (storage_backend) {
-
-					psa_its_frontend_init(storage_backend);
-					status = 0;
-				}
-			}
-
-			if (status < 0) relinquish_service_under_test();
-		}
-	}
-
-	return status;
-}
-
-int relinquish_service_under_test(void)
-{
-	psa_its_frontend_init(NULL);
-	secure_storage_client_deinit(&storage_client);
-
-	if (ps_service_context && session) {
-
-		service_context_close(ps_service_context, session);
-		session = NULL;
-	}
-
-	if (ps_service_context) {
-
-		service_context_relinquish(ps_service_context);
-		ps_service_context = NULL;
-	}
-
-	return 0;
-}
diff --git a/deployments/psa-api-test/internal_trusted_storage/linux-pc/CMakeLists.txt b/deployments/psa-api-test/internal_trusted_storage/linux-pc/CMakeLists.txt
index a123e30..506d1b0 100644
--- a/deployments/psa-api-test/internal_trusted_storage/linux-pc/CMakeLists.txt
+++ b/deployments/psa-api-test/internal_trusted_storage/linux-pc/CMakeLists.txt
@@ -20,6 +20,13 @@
 add_executable(${PROJECT_NAME})
 target_include_directories(${PROJECT_NAME} PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
+set(TRACE_PREFIX "PSAITS" CACHE STRING "Trace prefix")
+include(${TS_ROOT}/environments/linux-pc/env.cmake)
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS "environments/linux-pc"
+)
+
 #-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  psa-api-test/internal_trusted_storage
diff --git a/deployments/psa-api-test/protected_storage/arm-linux/CMakeLists.txt b/deployments/psa-api-test/protected_storage/arm-linux/CMakeLists.txt
index 412833f..8ff1ce6 100644
--- a/deployments/psa-api-test/protected_storage/arm-linux/CMakeLists.txt
+++ b/deployments/psa-api-test/protected_storage/arm-linux/CMakeLists.txt
@@ -18,6 +18,14 @@
 add_executable(${PROJECT_NAME})
 target_include_directories(${PROJECT_NAME} PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
+set(TRACE_PREFIX "PSAPS" CACHE STRING "Trace prefix")
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/common/trace"
+		"environments/arm-linux"
+)
+
 #-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  psa-api-test/protected_storage
diff --git a/deployments/psa-api-test/protected_storage/linux-pc/CMakeLists.txt b/deployments/psa-api-test/protected_storage/linux-pc/CMakeLists.txt
index 2131d34..ebfca44 100644
--- a/deployments/psa-api-test/protected_storage/linux-pc/CMakeLists.txt
+++ b/deployments/psa-api-test/protected_storage/linux-pc/CMakeLists.txt
@@ -20,6 +20,13 @@
 add_executable(${PROJECT_NAME})
 target_include_directories(${PROJECT_NAME} PRIVATE "${TOP_LEVEL_INCLUDE_DIRS}")
 
+set(TRACE_PREFIX "PSAPS" CACHE STRING "Trace prefix")
+include(${TS_ROOT}/environments/linux-pc/env.cmake)
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS "environments/linux-pc"
+)
+
 #-------------------------------------------------------------------------------
 #  Extend with components that are common across all deployments of
 #  psa-api-test/protected_storage
diff --git a/deployments/psa-api-test/protected_storage/ps-api-test.cmake b/deployments/psa-api-test/protected_storage/ps-api-test.cmake
index 9fa88fe..75bc974 100644
--- a/deployments/psa-api-test/protected_storage/ps-api-test.cmake
+++ b/deployments/psa-api-test/protected_storage/ps-api-test.cmake
@@ -22,17 +22,15 @@
 #  Protected storage specific components
 #
 #-------------------------------------------------------------------------------
-add_components(
-	TARGET "${PROJECT_NAME}"
-	BASE_DIR ${TS_ROOT}
-	COMPONENTS
-		"components/service/secure_storage/include"
-		"components/service/secure_storage/frontend/psa/ps"
-		"components/service/secure_storage/backend/secure_storage_client"
+target_sources(${PROJECT_NAME} PRIVATE
+	${TS_ROOT}/deployments/psa-api-test/protected_storage/ps.c
 )
 
-target_sources(${PROJECT_NAME} PRIVATE
-	${TS_ROOT}/deployments/psa-api-test/protected_storage/ps_locator.c
+add_components(TARGET ${PROJECT_NAME}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/service/common/include"
+		"components/service/secure_storage/include"
 )
 
 #-------------------------------------------------------------------------------
diff --git a/deployments/psa-api-test/protected_storage/ps.c b/deployments/psa-api-test/protected_storage/ps.c
new file mode 100644
index 0000000..2f0a800
--- /dev/null
+++ b/deployments/psa-api-test/protected_storage/ps.c
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "../psa_api_test_common.h"
+#include "libpsats.h"
+#include "trace.h"
+
+psa_status_t test_setup(const char *service_name_crypto, const char *service_name_iat,
+			const char *service_name_ps, const char *service_name_its)
+{
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+
+	if (!service_name_ps)
+		service_name_ps = "sn:trustedfirmware.org:protected-storage:0";
+
+	psa_status = libpsats_init_ps_context(service_name_ps);
+	if (psa_status) {
+		EMSG("libpsats_init_ps_context failed: %d\n", psa_status);
+		return psa_status;
+	}
+
+	return psa_status;
+}
+
+void test_teardown(void)
+{
+	libpsats_deinit_ps_context();
+}
diff --git a/deployments/psa-api-test/protected_storage/ps_locator.c b/deployments/psa-api-test/protected_storage/ps_locator.c
deleted file mode 100644
index aba8547..0000000
--- a/deployments/psa-api-test/protected_storage/ps_locator.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <stddef.h>
-#include <service_locator.h>
-#include <service/secure_storage/frontend/psa/ps/ps_frontend.h>
-#include <service/secure_storage/backend/secure_storage_client/secure_storage_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include "../service_under_test.h"
-
-/* RPC context */
-static struct rpc_caller_session *session = NULL;
-static struct service_context *ps_service_context = NULL;
-static struct secure_storage_client storage_client;
-
-int locate_service_under_test(void)
-{
-	int status = -1;
-
-	if (!session && !ps_service_context) {
-
-		service_locator_init();
-
-		ps_service_context =
-			service_locator_query("sn:trustedfirmware.org:protected-storage:0");
-
-		if (ps_service_context) {
-
-			session = service_context_open(ps_service_context);
-
-			if (session) {
-
-				struct storage_backend *storage_backend = NULL;
-
-				storage_backend = secure_storage_client_init(&storage_client,  session);
-
-				if (storage_backend) {
-
-					psa_ps_frontend_init(storage_backend);
-					status = 0;
-				}
-			}
-
-			if (status < 0) relinquish_service_under_test();
-		}
-	}
-
-	return status;
-}
-
-int relinquish_service_under_test(void)
-{
-	psa_ps_frontend_init(NULL);
-	secure_storage_client_deinit(&storage_client);
-
-	if (ps_service_context && session) {
-
-		service_context_close(ps_service_context, session);
-		session = NULL;
-	}
-
-	if (ps_service_context) {
-
-		service_context_relinquish(ps_service_context);
-		ps_service_context = NULL;
-	}
-
-	return 0;
-}
\ No newline at end of file
diff --git a/deployments/psa-api-test/psa-api-test.cmake b/deployments/psa-api-test/psa-api-test.cmake
index 739ed26..b005e26 100644
--- a/deployments/psa-api-test/psa-api-test.cmake
+++ b/deployments/psa-api-test/psa-api-test.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2021-2023, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -11,45 +11,36 @@
 #-------------------------------------------------------------------------------
 
 #-------------------------------------------------------------------------------
-#  Use libts for locating and accessing services. An appropriate version of
-#  libts will be imported for the environment in which service tests are
-#  deployed.
-#-------------------------------------------------------------------------------
-include(${TS_ROOT}/deployments/libts/libts-import.cmake)
-target_link_libraries(${PROJECT_NAME} PRIVATE libts::ts)
-
-#-------------------------------------------------------------------------------
 #  Components that are common across all deployments
 #
 #-------------------------------------------------------------------------------
-add_components(
-	TARGET "${PROJECT_NAME}"
-	BASE_DIR ${TS_ROOT}
-	COMPONENTS
-		"components/common/tlv"
-		"components/service/common/client"
-		"components/service/common/include"
-)
 
 target_sources(${PROJECT_NAME} PRIVATE
 	${TS_ROOT}/deployments/psa-api-test/arch_test_runner.c
 )
 
 #-------------------------------------------------------------------------------
+#  Use libpsats for locating PSA services. An appropriate version of
+#  libpsats will be imported for the environment. Making sure the link order is
+#  correct.
+#-------------------------------------------------------------------------------
+if (COVERAGE)
+	set(LIBPSATS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libpsats build type" FORCE)
+	set(LIBTS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libts build type" FORCE)
+endif()
+
+include(${TS_ROOT}/deployments/libpsats/libpsats-import.cmake)
+target_link_libraries( ${PROJECT_NAME} PRIVATE libpsats::psats)
+
+target_link_libraries(${PROJECT_NAME} PRIVATE val_nspe test_combine pal_nspe)
+
+#-------------------------------------------------------------------------------
 #  Export project header paths for arch tests
 #
 #-------------------------------------------------------------------------------
 get_target_property(_include_paths ${PROJECT_NAME} INCLUDE_DIRECTORIES)
 list(APPEND PSA_ARCH_TESTS_EXTERNAL_INCLUDE_PATHS ${_include_paths})
-
-#-------------------------------------------------------------------------------
-#  Components used from external projects
-#
-#-------------------------------------------------------------------------------
-
-# psa-arch-tests
 include(${TS_ROOT}/external/psa_arch_tests/psa_arch_tests.cmake)
-target_link_libraries(${PROJECT_NAME} PRIVATE val_nspe test_combine pal_nspe)
 
 #-------------------------------------------------------------------------------
 #  Define install content.
diff --git a/deployments/psa-api-test/psa_api_test_common.h b/deployments/psa-api-test/psa_api_test_common.h
new file mode 100644
index 0000000..568cf10
--- /dev/null
+++ b/deployments/psa-api-test/psa_api_test_common.h
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include "psa/error.h"
+
+psa_status_t test_setup(const char *service_name_crypto, const char *service_name_iat,
+			const char *service_name_ps, const char *service_name_its);
+void test_teardown(void);
+
+#endif /* COMMON_H */
diff --git a/deployments/psa-api-test/service_under_test.h b/deployments/psa-api-test/service_under_test.h
deleted file mode 100644
index 834384e..0000000
--- a/deployments/psa-api-test/service_under_test.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef SERVICE_UNDER_TEST_H
-#define SERVICE_UNDER_TEST_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * Locate and open an RPC session for the service under test.  Concrete
- * implementations of this function will locate a specific service and
- * associate an RPC Caller with the singleton PSA API client used by
- * the API tests.
- */
-int locate_service_under_test(void);
-
-/**
- * Reliquish the RPC session when the test run is complete.
- */
-int relinquish_service_under_test(void);
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* SERVICE_UNDER_TEST_H */
diff --git a/deployments/se-proxy/config/corstone1000-opteesp/CMakeLists.txt b/deployments/se-proxy/config/corstone1000-opteesp/CMakeLists.txt
index 8987b04..e521a6c 100644
--- a/deployments/se-proxy/config/corstone1000-opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/config/corstone1000-opteesp/CMakeLists.txt
@@ -74,7 +74,6 @@
 #TODO: api headers
 
 install(TARGETS se-proxy
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/se-proxy/config/corstone1000-opteesp/default_se-proxy.dts.in b/deployments/se-proxy/config/corstone1000-opteesp/default_se-proxy.dts.in
index 32e2ae3..823043d 100644
--- a/deployments/se-proxy/config/corstone1000-opteesp/default_se-proxy.dts.in
+++ b/deployments/se-proxy/config/corstone1000-opteesp/default_se-proxy.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "SE Proxy";
 	execution-ctx-count = <1>;
diff --git a/deployments/se-proxy/config/default-opteesp/CMakeLists.txt b/deployments/se-proxy/config/default-opteesp/CMakeLists.txt
index a1c2d8f..9eab64b 100644
--- a/deployments/se-proxy/config/default-opteesp/CMakeLists.txt
+++ b/deployments/se-proxy/config/default-opteesp/CMakeLists.txt
@@ -76,7 +76,6 @@
 #TODO: api headers
 
 install(TARGETS se-proxy
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/se-proxy/config/default-opteesp/default_se-proxy.dts.in b/deployments/se-proxy/config/default-opteesp/default_se-proxy.dts.in
index 7c2f038..9ef01a9 100644
--- a/deployments/se-proxy/config/default-opteesp/default_se-proxy.dts.in
+++ b/deployments/se-proxy/config/default-opteesp/default_se-proxy.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "SE Proxy";
 	execution-ctx-count = <1>;
diff --git a/deployments/se-proxy/config/default-sp/CMakeLists.txt b/deployments/se-proxy/config/default-sp/CMakeLists.txt
index 9131088..2442fd6 100644
--- a/deployments/se-proxy/config/default-sp/CMakeLists.txt
+++ b/deployments/se-proxy/config/default-sp/CMakeLists.txt
@@ -78,7 +78,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS se-proxy
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/se-proxy/config/default-sp/default_se-proxy.dts.in b/deployments/se-proxy/config/default-sp/default_se-proxy.dts.in
index 09f0dc1..e964909 100644
--- a/deployments/se-proxy/config/default-sp/default_se-proxy.dts.in
+++ b/deployments/se-proxy/config/default-sp/default_se-proxy.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "SE Proxy";
 	execution-ctx-count = <1>;
diff --git a/deployments/se-proxy/env/commonsp/se_proxy_sp.c b/deployments/se-proxy/env/commonsp/se_proxy_sp.c
index 155e948..485d764 100644
--- a/deployments/se-proxy/env/commonsp/se_proxy_sp.c
+++ b/deployments/se-proxy/env/commonsp/se_proxy_sp.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  */
 
 #include "components/rpc/common/endpoint/rpc_service_interface.h"
@@ -39,7 +39,7 @@
 		goto fatal_error;
 	}
 
-	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 4, 16);
+	rpc_status = ts_rpc_endpoint_sp_init(&rpc_endpoint, 5, 16);
 	if (rpc_status != RPC_SUCCESS) {
 		EMSG("Failed to initialize RPC endpoint: %d", rpc_status);
 		goto fatal_error;
@@ -94,6 +94,18 @@
 		goto fatal_error;
 	}
 
+	rpc_iface = fwu_proxy_create();
+	if (!rpc_iface) {
+		EMSG("Failed to create FWU proxy");
+		goto fatal_error;
+	}
+
+	rpc_status = ts_rpc_endpoint_sp_add_service(&rpc_endpoint, rpc_iface);
+	if (rpc_status != RPC_SUCCESS) {
+		EMSG("Failed to add service to RPC endpoint: %d", rpc_status);
+		goto fatal_error;
+	}
+
 	/* End of boot phase */
 	result = sp_msg_wait(&req_msg);
 	if (result != SP_RESULT_OK) {
@@ -126,6 +138,22 @@
 	(void)interrupt_id;
 }
 
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
 static bool sp_init(uint16_t *own_id)
 {
 	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
diff --git a/deployments/se-proxy/infra/corstone1000/infra.cmake b/deployments/se-proxy/infra/corstone1000/infra.cmake
index a52a1b7..3830f9d 100644
--- a/deployments/se-proxy/infra/corstone1000/infra.cmake
+++ b/deployments/se-proxy/infra/corstone1000/infra.cmake
@@ -14,13 +14,19 @@
 add_components(TARGET "se-proxy"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"components/common/uuid"
 		"components/rpc/common/caller"
-		"components/rpc/rss_comms"
-		"components/messaging/rss_comms/sp"
+		"components/rpc/rse_comms"
+		"components/messaging/rse_comms/sp"
 		"components/service/attestation/client/psa_ipc"
 		"components/service/attestation/key_mngr/local"
 		"components/service/attestation/reporter/psa_ipc"
 		"components/service/crypto/backend/psa_ipc"
+		"components/service/fwu/common"
+		"components/service/fwu/provider"
+		"components/service/fwu/provider/serializer"
+		"components/service/fwu/psa_fwu_m/agent"
+		"components/service/fwu/psa_fwu_m/interface/stub"
 		"components/service/secure_storage/backend/secure_storage_ipc"
 )
 
diff --git a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
index b3b93cf..759983b 100644
--- a/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
+++ b/deployments/se-proxy/infra/corstone1000/service_proxy_factory.c
@@ -8,10 +8,12 @@
 #include <stddef.h>
 #include <psa/sid.h>
 #include "rpc/common/endpoint/rpc_service_interface.h"
-#include <rpc/rss_comms/caller/sp/rss_comms_caller.h>
+#include <rpc/rse_comms/caller/sp/rse_comms_caller.h>
 #include <service/attestation/provider/attest_provider.h>
 #include <service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h>
 #include <service/crypto/factory/crypto_provider_factory.h>
+#include "service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.h"
+#include "service/fwu/provider/fwu_provider.h"
 #include <service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h>
 #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 #include <trace.h>
@@ -29,15 +31,15 @@
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Static objects for proxy instance */
-	static struct rpc_caller_interface rss_comms = { 0 };
+	static struct rpc_caller_interface rse_comms = { 0 };
 	static struct rpc_caller_session rpc_session = { 0 };
 	static struct attest_provider attest_provider = { 0 };
 
-	rpc_status = rss_comms_caller_init(&rss_comms);
+	rpc_status = rse_comms_caller_init(&rse_comms);
 	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
-	rpc_status = rpc_caller_session_open(&rpc_session, &rss_comms, &dummy_uuid, 0, 0);
+	rpc_status = rpc_caller_session_open(&rpc_session, &rse_comms, &dummy_uuid, 0, 0);
 	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
@@ -58,14 +60,14 @@
 	rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
 
 	/* Static objects for proxy instance */
-	static struct rpc_caller_interface rss_comms = { 0 };
+	static struct rpc_caller_interface rse_comms = { 0 };
 	static struct rpc_caller_session rpc_session = { 0 };
 
-	rpc_status = rss_comms_caller_init(&rss_comms);
+	rpc_status = rse_comms_caller_init(&rse_comms);
 	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
-	rpc_status = rpc_caller_session_open(&rpc_session, &rss_comms, &dummy_uuid, 0, 0);
+	rpc_status = rpc_caller_session_open(&rpc_session, &rse_comms, &dummy_uuid, 0, 0);
 	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
@@ -87,14 +89,14 @@
 	const struct rpc_uuid ps_uuid = { .uuid = TS_PSA_PROTECTED_STORAGE_UUID };
 
 	/* Static objects for proxy instance */
-	static struct rpc_caller_interface rss_comms = { 0 };
+	static struct rpc_caller_interface rse_comms = { 0 };
 	static struct rpc_caller_session rpc_session = { 0 };
 
-	rpc_status = rss_comms_caller_init(&rss_comms);
+	rpc_status = rse_comms_caller_init(&rse_comms);
 	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
-	rpc_status = rpc_caller_session_open(&rpc_session, &rss_comms, &dummy_uuid, 0, 0);
+	rpc_status = rpc_caller_session_open(&rpc_session, &rse_comms, &dummy_uuid, 0, 0);
 	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
@@ -113,14 +115,14 @@
 	const struct rpc_uuid its_uuid = { .uuid = TS_PSA_INTERNAL_TRUSTED_STORAGE_UUID };
 
 	/* Static objects for proxy instance */
-	static struct rpc_caller_interface rss_comms = { 0 };
+	static struct rpc_caller_interface rse_comms = { 0 };
 	static struct rpc_caller_session rpc_session = { 0 };
 
-	rpc_status = rss_comms_caller_init(&rss_comms);
+	rpc_status = rse_comms_caller_init(&rse_comms);
 	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
-	rpc_status = rpc_caller_session_open(&rpc_session, &rss_comms, &dummy_uuid, 0, 0);
+	rpc_status = rpc_caller_session_open(&rpc_session, &rse_comms, &dummy_uuid, 0, 0);
 	if (rpc_status != RPC_SUCCESS)
 		return NULL;
 
@@ -129,3 +131,13 @@
 
 	return secure_storage_provider_init(&its_provider, backend, &its_uuid);
 }
+
+struct rpc_service_interface *fwu_proxy_create(void)
+{
+	static struct update_agent *agent;
+	static struct fwu_provider fwu_provider = { 0 };
+
+	agent = psa_fwu_m_update_agent_init(NULL, 0, 4096);
+
+	return fwu_provider_init(&fwu_provider, agent);
+}
diff --git a/deployments/se-proxy/infra/service_proxy_factory.h b/deployments/se-proxy/infra/service_proxy_factory.h
index caaea79..be83319 100644
--- a/deployments/se-proxy/infra/service_proxy_factory.h
+++ b/deployments/se-proxy/infra/service_proxy_factory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -17,6 +17,7 @@
 struct rpc_service_interface *crypto_proxy_create(void);
 struct rpc_service_interface *ps_proxy_create(void);
 struct rpc_service_interface *its_proxy_create(void);
+struct rpc_service_interface *fwu_proxy_create(void);
 
 #ifdef __cplusplus
 }
diff --git a/deployments/se-proxy/infra/stub/service_proxy_factory.c b/deployments/se-proxy/infra/stub/service_proxy_factory.c
index 4cec9ce..0a8e6de 100644
--- a/deployments/se-proxy/infra/stub/service_proxy_factory.c
+++ b/deployments/se-proxy/infra/stub/service_proxy_factory.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,6 +9,8 @@
 #include "service/attestation/provider/attest_provider.h"
 #include "service/attestation/provider/serializer/packed-c/packedc_attest_provider_serializer.h"
 #include "service/crypto/factory/crypto_provider_factory.h"
+#include "service/fwu/psa_fwu_m/agent/psa_fwu_m_update_agent.h"
+#include "service/fwu/provider/fwu_provider.h"
 #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_provider.h"
 #include "service/secure_storage/frontend/secure_storage_provider/secure_storage_uuid.h"
 
@@ -67,3 +69,13 @@
 
 	return secure_storage_provider_init(&its_provider, backend, &service_uuid);
 }
+
+struct rpc_service_interface *fwu_proxy_create(void)
+{
+	static struct update_agent *agent;
+	static struct fwu_provider fwu_provider = { 0 };
+
+	agent = psa_fwu_m_update_agent_init(NULL, 0, 4096);
+
+	return fwu_provider_init(&fwu_provider, agent);
+}
diff --git a/deployments/se-proxy/infra/stub/stub.cmake b/deployments/se-proxy/infra/stub/stub.cmake
index a364f8d..58beacd 100644
--- a/deployments/se-proxy/infra/stub/stub.cmake
+++ b/deployments/se-proxy/infra/stub/stub.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -14,12 +14,18 @@
 add_components(TARGET "se-proxy"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"components/common/uuid"
 		"components/rpc/dummy"
 		"components/rpc/common/caller"
 		"components/service/attestation/reporter/stub"
 		"components/service/attestation/key_mngr/stub"
 		"components/service/crypto/backend/stub"
 		"components/service/crypto/client/psa"
+		"components/service/fwu/common"
+		"components/service/fwu/provider"
+		"components/service/fwu/provider/serializer"
+		"components/service/fwu/psa_fwu_m/agent"
+		"components/service/fwu/psa_fwu_m/interface/stub"
 		"components/service/secure_storage/backend/mock_store"
 )
 
diff --git a/deployments/smm-gateway/common/smm_gateway.c b/deployments/smm-gateway/common/smm_gateway.c
index eaa8613..3ab45cc 100644
--- a/deployments/smm-gateway/common/smm_gateway.c
+++ b/deployments/smm-gateway/common/smm_gateway.c
@@ -40,10 +40,6 @@
 #define SMM_UEFI_VARIABLE_STORE_INDEX_SIZE \
 	UEFI_VARIABLE_STORE_INDEX_SIZE(SMM_GATEWAY_MAX_UEFI_VARIABLES)
 
-_Static_assert(SMM_UEFI_VARIABLE_STORE_INDEX_SIZE < RPC_CALLER_SESSION_SHARED_MEMORY_SIZE,
-	       "The UEFI variable index does not fit into the RPC shared memory, please increase " \
-	       "RPC_CALLER_SESSION_SHARED_MEMORY_SIZE");
-
 /**
  * The SP heap must be large enough for storing the UEFI variable index, the RPC shared memory and
  * ~16kB of miscellaneous data.
diff --git a/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt b/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
index 39d4f60..94ff14c 100644
--- a/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
+++ b/deployments/smm-gateway/config/default-opteesp/CMakeLists.txt
@@ -42,7 +42,7 @@
 add_platform(TARGET "smm-gateway")
 
 # SMM variable and RPC caller settings
-set(SMM_GATEWAY_MAX_UEFI_VARIABLES 40 CACHE STRING "Maximum UEFI variable count")
+set(SMM_GATEWAY_MAX_UEFI_VARIABLES 35 CACHE STRING "Maximum UEFI variable count")
 set(SMM_RPC_CALLER_SESSION_SHARED_MEMORY_SIZE 2*4096 CACHE STRING "RPC caller buffer size in SMMGW")
 if (UEFI_AUTH_VAR)
 set(SMM_SP_HEAP_SIZE 64*1024 CACHE STRING "SMM gateway SP heap size")
@@ -106,7 +106,6 @@
 #TODO: api headers
 
 install(TARGETS smm-gateway
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/smm-gateway/config/default-opteesp/default_smm-gateway.dts.in b/deployments/smm-gateway/config/default-opteesp/default_smm-gateway.dts.in
index eb5ebf5..611bfd6 100644
--- a/deployments/smm-gateway/config/default-opteesp/default_smm-gateway.dts.in
+++ b/deployments/smm-gateway/config/default-opteesp/default_smm-gateway.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "SMM Gateway";
 	execution-ctx-count = <1>;
diff --git a/deployments/smm-gateway/config/default-sp/CMakeLists.txt b/deployments/smm-gateway/config/default-sp/CMakeLists.txt
index 102c3ee..e92f163 100644
--- a/deployments/smm-gateway/config/default-sp/CMakeLists.txt
+++ b/deployments/smm-gateway/config/default-sp/CMakeLists.txt
@@ -47,7 +47,7 @@
 add_platform(TARGET "smm-gateway")
 
 # SMM variable and RPC caller settings
-set(SMM_GATEWAY_MAX_UEFI_VARIABLES 40 CACHE STRING "Maximum UEFI variable count")
+set(SMM_GATEWAY_MAX_UEFI_VARIABLES 35 CACHE STRING "Maximum UEFI variable count")
 set(SMM_RPC_CALLER_SESSION_SHARED_MEMORY_SIZE 2*4096 CACHE STRING "RPC caller buffer size in SMMGW")
 if (UEFI_AUTH_VAR)
 set(SMM_SP_HEAP_SIZE 64*1024 CACHE STRING "SMM gateway SP heap size")
@@ -107,7 +107,6 @@
 	set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH "location to install build output to." FORCE)
 endif()
 install(TARGETS smm-gateway
-			PUBLIC_HEADER DESTINATION ${TS_ENV}/include
 			RUNTIME DESTINATION ${TS_ENV}/bin
 		)
 
diff --git a/deployments/smm-gateway/config/default-sp/default_smm-gateway.dts.in b/deployments/smm-gateway/config/default-sp/default_smm-gateway.dts.in
index 8e41eb7..0d6df35 100644
--- a/deployments/smm-gateway/config/default-sp/default_smm-gateway.dts.in
+++ b/deployments/smm-gateway/config/default-sp/default_smm-gateway.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <@EXPORT_SP_UUID_DT@>;
 	description = "SMM Gateway";
 	execution-ctx-count = <1>;
diff --git a/deployments/smm-gateway/env/commonsp/smm_gateway_sp.c b/deployments/smm-gateway/env/commonsp/smm_gateway_sp.c
index bb2d0c3..9edc3c7 100644
--- a/deployments/smm-gateway/env/commonsp/smm_gateway_sp.c
+++ b/deployments/smm-gateway/env/commonsp/smm_gateway_sp.c
@@ -127,6 +127,22 @@
 	(void)interrupt_id;
 }
 
+ffa_result ffa_vm_created_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
+ffa_result ffa_vm_destroyed_handler(uint16_t vm_id, uint64_t handle)
+{
+	(void)vm_id;
+	(void)handle;
+
+	return FFA_OK;
+}
+
 static bool sp_init(uint16_t *own_id)
 {
 	sp_result sp_res = SP_RESULT_INTERNAL_ERROR;
diff --git a/deployments/smm-gateway/smm-gateway.cmake b/deployments/smm-gateway/smm-gateway.cmake
index e5ee03b..bbeb034 100644
--- a/deployments/smm-gateway/smm-gateway.cmake
+++ b/deployments/smm-gateway/smm-gateway.cmake
@@ -11,12 +11,18 @@
 
 # If enabled an internal mbedtls instance will be used instead of the crypto SP
 if (UEFI_INTERNAL_CRYPTO)
-set(MBEDTLS_USER_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/x509_only.h"
+set(MBEDTLS_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/internal_crypto_smmgw.h"
 	CACHE STRING "Configuration file for Mbed TLS" FORCE)
 include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
 target_link_libraries(smm-gateway PRIVATE MbedTLS::mbedcrypto)
 target_link_libraries(smm-gateway PRIVATE MbedTLS::mbedx509)
 
+# Pass the mbedtls config file to C preprocessor so the uefi
+# direct backend will access the mbedtls headers
+target_compile_definitions(smm-gateway PRIVATE
+	MBEDTLS_CONFIG_FILE="${MBEDTLS_CONFIG_FILE}"
+)
+
 target_compile_definitions(smm-gateway PRIVATE
 	-DUEFI_INTERNAL_CRYPTO
 )
@@ -24,7 +30,9 @@
 add_components(TARGET "smm-gateway"
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
+		"components/common/mbedtls"
 		"components/service/uefi/smm_variable/backend/direct"
+		"components/service/crypto/backend/mbedcrypto/trng_adapter/stub"
 )
 
 else()
diff --git a/deployments/spm-test1/opteesp/default_spm_test1.dts.in b/deployments/spm-test1/opteesp/default_spm_test1.dts.in
index 14b0c34..9d1f719 100644
--- a/deployments/spm-test1/opteesp/default_spm_test1.dts.in
+++ b/deployments/spm-test1/opteesp/default_spm_test1.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 
 	/* Properties */
 	description = "SPMC test SP1";
diff --git a/deployments/spm-test2/opteesp/CMakeLists.txt b/deployments/spm-test2/opteesp/CMakeLists.txt
index 1c688f1..fc90d52 100644
--- a/deployments/spm-test2/opteesp/CMakeLists.txt
+++ b/deployments/spm-test2/opteesp/CMakeLists.txt
@@ -19,6 +19,8 @@
 set(SP_HEAP_SIZE "32 * 1024" CACHE STRING "SP heap size in bytes")
 set(SP_BOOT_ORDER "0" CACHE STRING "Boot order of the SP")
 set(TRACE_PREFIX "SPM-TEST${SP_NUMBER}" CACHE STRING "Trace prefix")
+# SPM test SP2 is set to use FF-A v1.0 to cover v1.0 support as well
+set(FFA_VERSION 0x00010000 CACHE STRING "The supported FF-A protocol's version: (major << 16) | minor")
 
 #-------------------------------------------------------------------------------
 #  Components that are spm-test specific to deployment in the opteesp
diff --git a/deployments/spm-test2/opteesp/default_spm_test2.dts.in b/deployments/spm-test2/opteesp/default_spm_test2.dts.in
index 2364ded..034fe22 100644
--- a/deployments/spm-test2/opteesp/default_spm_test2.dts.in
+++ b/deployments/spm-test2/opteesp/default_spm_test2.dts.in
@@ -8,6 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
+	/* SPM test SP2 is set to use FF-A v1.0 to cover v1.0 support as well */
 	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
 
 	/* Properties */
diff --git a/deployments/spm-test3/opteesp/default_spm_test3.dts.in b/deployments/spm-test3/opteesp/default_spm_test3.dts.in
index 17e9a47..2f7605b 100644
--- a/deployments/spm-test3/opteesp/default_spm_test3.dts.in
+++ b/deployments/spm-test3/opteesp/default_spm_test3.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 
 	/* Properties */
 	description = "SPMC test SP3";
diff --git a/deployments/spm-test4/opteesp/default_spm_test4.dts.in b/deployments/spm-test4/opteesp/default_spm_test4.dts.in
index ac57dcd..093c4e4 100644
--- a/deployments/spm-test4/opteesp/default_spm_test4.dts.in
+++ b/deployments/spm-test4/opteesp/default_spm_test4.dts.in
@@ -8,7 +8,7 @@
 
 @DTS_NODE@ {
 	compatible = "arm,ffa-manifest-1.0";
-	ffa-version = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	ffa-version = <@CFG_FFA_VERSION@>; /* 31:16 - Major, 15:0 - Minor */
 
 	/* Properties */
 	description = "SPMC test SP4";
diff --git a/deployments/ts-demo/ts-demo.c b/deployments/ts-demo/ts-demo.c
new file mode 100644
index 0000000..5efce9f
--- /dev/null
+++ b/deployments/ts-demo/ts-demo.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <app/ts-demo/ts-demo.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libpsats.h"
+
+int main(int argc, char *argv[])
+{
+	psa_status_t psa_status = PSA_ERROR_GENERIC_ERROR;
+	const char *service_name = "sn:trustedfirmware.org:crypto:0";
+
+	if (argc > 1)
+		service_name = argv[1];
+
+	psa_status = libpsats_init_crypto_context(service_name);
+
+	if (psa_status) {
+		printf("libpsats_init_crypto_context failed: %d\n", psa_status);
+		return psa_status;
+	}
+
+	psa_status = run_ts_demo(true);
+
+	libpsats_deinit_its_context();
+
+	if (psa_status)
+		printf("\n*** ts-demo failed ***\n\n");
+	else
+		printf("\n*** ts-demo was successful ***\n\n");
+
+	return psa_status;
+}
diff --git a/deployments/ts-demo/ts-demo.cmake b/deployments/ts-demo/ts-demo.cmake
index 0769df9..b663fb6 100644
--- a/deployments/ts-demo/ts-demo.cmake
+++ b/deployments/ts-demo/ts-demo.cmake
@@ -12,19 +12,23 @@
 #-------------------------------------------------------------------------------
 
 #-------------------------------------------------------------------------------
-#  Use libts for locating and accessing services. An appropriate version of
-#  libts will be imported for the environment in which service tests are
-#  deployed.
+#  Use libpsats for locating PSA services. An appropriate version of
+#  libpsats will be imported for the environment.
 #-------------------------------------------------------------------------------
-include(${TS_ROOT}/deployments/libts/libts-import.cmake)
-target_link_libraries(ts-demo PRIVATE libts::ts)
+if (COVERAGE)
+	set(LIBPSATS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libpsats build type" FORCE)
+	set(LIBTS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libts build type" FORCE)
+endif()
+
+include(${TS_ROOT}/deployments/libpsats/libpsats-import.cmake)
+target_link_libraries(ts-demo PRIVATE libpsats::psats)
 
 #-------------------------------------------------------------------------------
 #  Common main for all deployments
 #
 #-------------------------------------------------------------------------------
 target_sources(ts-demo PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/ts-demo.cpp"
+	"${CMAKE_CURRENT_LIST_DIR}/ts-demo.c"
 )
 
 #-------------------------------------------------------------------------------
@@ -36,26 +40,9 @@
 	BASE_DIR ${TS_ROOT}
 	COMPONENTS
 		"components/app/ts-demo"
-		"components/common/tlv"
-		"components/service/common/include"
-		"components/service/common/client"
-		"components/service/crypto/client/cpp"
-		"components/service/crypto/client/cpp/protocol/packed-c"
-		"protocols/service/crypto/packed-c"
 )
 
 #-------------------------------------------------------------------------------
-#  Components used from external projects
-#
-#-------------------------------------------------------------------------------
-
-# MbedTLS provides libmbedcrypto
-set(MBEDTLS_USER_CONFIG_FILE "${TS_ROOT}/external/MbedTLS/config/crypto_posix.h"
-	CACHE STRING "Configuration file for mbedcrypto")
-include(${TS_ROOT}/external/MbedTLS/MbedTLS.cmake)
-target_link_libraries(ts-demo PRIVATE MbedTLS::mbedcrypto)
-
-#-------------------------------------------------------------------------------
 #  Define install content.
 #
 #-------------------------------------------------------------------------------
diff --git a/deployments/ts-demo/ts-demo.cpp b/deployments/ts-demo/ts-demo.cpp
deleted file mode 100644
index 55948a3..0000000
--- a/deployments/ts-demo/ts-demo.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-// SPDX-License-Identifier: BSD-2-Clause
-/*
- * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
- */
-
-#include <cstdio>
-#include <service/crypto/client/cpp/protocol/packed-c/packedc_crypto_client.h>
-#include <protocols/rpc/common/packed-c/encoding.h>
-#include <app/ts-demo/ts-demo.h>
-#include <service_locator.h>
-#include <rpc_caller.h>
-
-int main(int argc, char *argv[]) {
-	(void) argc;
-	(void) argv;
-
-	int status = -1;
-	struct service_context *crypto_service_context = NULL;
-
-	service_locator_init();
-
-	crypto_service_context = service_locator_query("sn:trustedfirmware.org:crypto:0");
-
-	if (crypto_service_context) {
-
-		struct rpc_caller_session *session = NULL;
-
-		session = service_context_open(crypto_service_context);
-
-		if (session) {
-
-			packedc_crypto_client crypto_client(session);
-
-			status = run_ts_demo(&crypto_client, true);
-
-			if (status != 0) {
-				printf("run_ts_demo failed\n");
-			}
-
-			service_context_close(crypto_service_context, session);
-		}
-		else {
-			printf("Failed to open rpc session\n");
-		}
-
-		service_context_relinquish(crypto_service_context);
-	}
-	else {
-		printf("Failed to discover crypto service\n");
-	}
-
-	return status;
-}
diff --git a/deployments/ts-remote-test/ts-remote-test.cmake b/deployments/ts-remote-test/ts-remote-test.cmake
index 0bdeb9b..ada5d1a 100644
--- a/deployments/ts-remote-test/ts-remote-test.cmake
+++ b/deployments/ts-remote-test/ts-remote-test.cmake
@@ -16,6 +16,10 @@
 #  libts will be imported for the environment in which tests are
 #  deployed.
 #-------------------------------------------------------------------------------
+if (COVERAGE)
+	set(LIBTS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libts build type" FORCE)
+endif()
+
 include(${TS_ROOT}/deployments/libts/libts-import.cmake)
 target_link_libraries(ts-remote-test PRIVATE libts::ts)
 
diff --git a/deployments/ts-service-test/linux-pc/CMakeLists.txt b/deployments/ts-service-test/linux-pc/CMakeLists.txt
index b0cd912..410eaae 100644
--- a/deployments/ts-service-test/linux-pc/CMakeLists.txt
+++ b/deployments/ts-service-test/linux-pc/CMakeLists.txt
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -97,6 +97,7 @@
 		"components/service/block_storage/test/service"
 		"components/service/common/provider"
 		"components/service/fwu/agent"
+		"components/service/fwu/common"
 		"components/service/fwu/fw_store/banked"
 		"components/service/fwu/fw_store/banked/metadata_serializer/v1"
 		"components/service/fwu/fw_store/banked/metadata_serializer/v2"
@@ -105,7 +106,7 @@
 		"components/service/fwu/installer/copy"
 		"components/service/fwu/inspector/direct"
 		"components/service/fwu/provider"
-		"components/service/fwu/provider/serializer/packed-c"
+		"components/service/fwu/provider/serializer"
 		"components/service/fwu/test/fwu_client/direct"
 		"components/service/fwu/test/fwu_dut/sim"
 		"components/service/fwu/test/fwu_dut_factory/remote_sim"
diff --git a/deployments/ts-service-test/ts-service-test.cmake b/deployments/ts-service-test/ts-service-test.cmake
index 925cedd..5437e74 100644
--- a/deployments/ts-service-test/ts-service-test.cmake
+++ b/deployments/ts-service-test/ts-service-test.cmake
@@ -16,6 +16,10 @@
 #  libts will be imported for the environment in which service tests are
 #  deployed.
 #-------------------------------------------------------------------------------
+if (COVERAGE)
+	set(LIBTS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libts build type" FORCE)
+endif()
+
 include(${TS_ROOT}/deployments/libts/libts-import.cmake)
 target_link_libraries(ts-service-test PRIVATE libts::ts)
 
@@ -76,6 +80,15 @@
 )
 
 #-------------------------------------------------------------------------------
+#  Component configurations
+#
+#-------------------------------------------------------------------------------
+target_compile_definitions(ts-service-test PRIVATE
+	"TRACE_PREFIX=\"TEST\""
+	"TRACE_LEVEL=0"
+)
+
+#-------------------------------------------------------------------------------
 #  Components used from external projects
 #
 #-------------------------------------------------------------------------------
diff --git a/deployments/uefi-test/uefi-test.cmake b/deployments/uefi-test/uefi-test.cmake
index 9e43d6f..fda92ab 100644
--- a/deployments/uefi-test/uefi-test.cmake
+++ b/deployments/uefi-test/uefi-test.cmake
@@ -17,6 +17,10 @@
 #  libts will be imported for the enviroment in which service tests are
 #  deployed.
 #-------------------------------------------------------------------------------
+if (COVERAGE)
+	set(LIBTS_BUILD_TYPE "DEBUGCOVERAGE" CACHE STRING "Libts build type" FORCE)
+endif()
+
 include(${TS_ROOT}/deployments/libts/libts-import.cmake)
 target_link_libraries(uefi-test PRIVATE libts::ts)
 
diff --git a/docs/conf.py b/docs/conf.py
index ee9a1aa..e84f597 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -47,7 +47,7 @@
 #
 # This is also used if you do content translation via gettext catalogs.
 # Usually you set "language" from the command line for these cases.
-language = None
+language = 'en'
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
@@ -102,3 +102,28 @@
 # -- Options for plantuml ----------------------------------------------------
 
 plantuml_output_format = 'svg_img'
+
+# if plantuml wrapper executable is specified use it.
+_p=os.environ.get('PLANTUML')
+if _p is None:
+    # if a specific jar file is specified use it with an "inline" wrapper
+    jar=os.environ.get('PLANTUML_JAR_PATH')
+    if jar is not None:
+        # if JAVA_HOME look for the JVM under that location
+        java_home=os.environ.get('JAVA_HOME')
+        if java_home is not None:
+            java=os.path.join(java_home, "bin", "java")
+        else:
+            # if not, look for JVM on the PATH
+            import shutil
+            java=shutil.which("java")
+        # if the JVM does not exist, fall back to java
+        if not os.path.exists(java):
+                java='java'
+        # Set the wrapper command
+        _p="%s -Djava.awt.headless=true -Djava.net.useSystemProxies=true -jar %s" % (java, jar)
+
+# if a plantuml executable was discovered, use that, or leave the default value
+# unchanged
+if _p is not None:
+    plantuml=_p
\ No newline at end of file
diff --git a/docs/deployments/libraries.rst b/docs/deployments/libraries.rst
index 25902ef..8a0e276 100644
--- a/docs/deployments/libraries.rst
+++ b/docs/deployments/libraries.rst
@@ -4,10 +4,19 @@
 other deployments or external applications. The following library deployments
 are currently supported:
 
+The libraries will have a build type-specific suffix added to the base name of
+their binaries, allowing multiple binaries to be installed in the same tree.
+(See :ref:`Selecting the build type`) This differentiation applies to the
+``Debug`` and ``DebugCoverage`` build types. The system integrator must choose
+which single ``Release<XXX>`` build type is to be supported in the system.
+Package managers and mutually exclusive release packages can be used to add
+further flexibility.
+
 .. _libs-libts:
 
 libts
 -----
+
 Userspace applications that depend on trusted services may use *libts* for handling
 service discovery and RPC messaging. A major benefit to application developers is
 that *libts* entirely decouples client applications from details of where a service
@@ -29,12 +38,89 @@
     - * | *linux-pc* - service providers integrated into library
       * | *arm-linux* - communicates with service providers in secure processing environment
   * - Used by
+    - * Userspace applications.
+
+
+.. _libs-libpsats:
+
+libpsats
+--------
+
+Trusted Services implements the `PSA Certified APIs`_. Libpsats encapsulates the service client implementations
+which implement this API. Linux uuser-space applications can use libpsats to easily access the PSA services
+implemented by the project. Libpsats depends on libts for RPC and service discovery services.
+
+.. list-table::
+  :widths: 1 2
+  :header-rows: 0
+
+  * - Supported Environments
+    - * | *linux-pc*
+      * | *arm-linux*
+  * - Used by
     - * Userspace applications
+  * - Depends on
+    - * `libts`_ library
+
+Build and integration examples
+..............................
+
+Build as shared library::
+
+  cmake -S ./trusted-services/deployments/libpsats/linux-pc/ -B ./build
+  make -C build && make -C build install
+
+.. warning::
+    Building as static library is not yet supported.
+
+To integrate the library libts shall also be integrated. To achieve this add the listed
+lines to the application's cmake files::
+
+  find_package(libpsats "1.0.0" REQUIRED PATHS "<install path>")
+  find_package(libts "2.0.0" REQUIRED PATHS "<install path>")
+  target_link_libraries(ts-demo PRIVATE libpsats::psats)
+
+Initialization
+..............
+
+Before calling any function from libpsats the proper part of the library has to be initialized.
+Before exiting the application (or when PSA services are no longer needed) the initialized
+parts must be deinitialized. To access the library **libpsats.h** must be included::
+
+   psa_status_t libpsats_init_crypto_context(const char *service_name);
+   void libpsats_deinit_crypto_context(void);
+
+   psa_status_t libpsats_init_attestation_context(const char *service_name);
+   void libpsats_deinit_attestation_context(void);
+
+   psa_status_t libpsats_init_its_context(const char *service_name);
+   void libpsats_deinit_its_context(void);
+
+   psa_status_t libpsats_init_ps_context(const char *service_name);
+   void libpsats_deinit_ps_context(void);
+
+The example below initializes and then deinitializes crypto::
+
+    psa_status_t psa_status = libpsats_init_crypto_context("sn:trustedfirmware.org:crypto:0");
+    if (psa_status) {
+        printf("libpsats_init_crypto_context failed: %d\n", psa_status);
+        return PSA_ERROR_GENERIC_ERROR;
+    }
+
+    libpsats_deinit_crypto_context();
+
+Known issues and Limitations
+............................
+
+| The library is single client.
+| The library is not thread safe.
+| Only linux user-space is supported currently.
 
 .. _libs-libsp:
 
 libsp
 -----
+
 *libsp* provides a functional interface for using FF-A messaging and memory
 management facilities. *libsp* is used in SP deployments. For more information, see:
 :ref:`libsp`.
@@ -48,8 +134,17 @@
   * - Used by
     - * Secure partitions
 
+Known issues and Limitations
+............................
+
+| The library is single client.
+| The library is not thread safe.
+| Only linux user-space is supported currently.
+
 --------------
 
-*Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.*
+.. _`PSA Certified APIs`: https://arm-software.github.io/psa-api/
+
+*Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.*
 
 SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/developer/build-instructions.rst b/docs/developer/build-instructions.rst
index f52fe55..5e8e333 100644
--- a/docs/developer/build-instructions.rst
+++ b/docs/developer/build-instructions.rst
@@ -25,10 +25,12 @@
 
 .. uml:: uml/BuildFlow.puml
 
+.. _`Selecting the build type`:
+
 Selecting the build type
 -------------------------
 The build type selects code optimization and debug information related compiler settings. The build system follows the
-standard CMake methodology and uses the `CMAKE_BUILD_TYPE`_ variable.
+standard CMake methodology and can be controlled with the `CMAKE_BUILD_TYPE`_ variable.
 
 The build system uses the following build types:
 
@@ -37,27 +39,43 @@
 
    * - Build type
      - Purpose
+     - Shared library suffix
      - Description
    * - Debug
      - For debugging purposes.
+     - `d`
      - Optimization is off, debugging information generation is enabled.
+   * - DebugCoverage
+     - For coverage measurement purposes.
+     - `c`
+     - Optimization is off, debugging information generation is enabled, code is compiled to enable gcov based coverage
+       measurement.
    * - MinSizeRel
      - Size optimized release build.
+     - None.
      - Optimization is configured to prefer small code size, debugging information is not generated.
    * - MinSizWithDebInfo
      - For debugging size optimized release build.
+     - None.
      - Optimization is configured to prefer small code size, debugging information generation is enabled.
    * - Release
      - Speed optimized release build.
+     - None.
      - Optimization is configured to prefer execution speed, debugging information is not generated.
    * - RelWithDebugInfo
      - For debugging speed optimized release build.
+     - None.
      - Optimization is configured to prefer execution speed, debugging information generation is enabled.
 
-Build type of external components can be configured with command line parameters. Parameter names follow this pattern:
+Build type of external components can be configured with command line arguments. Argument names follow this pattern:
 ``-D<upper case component name>_BUILD_TYPE=<value>`` e.g. ``-DNANOPB_BUILD_TYPE=Release``. Supported values are
 component specific, please refer to the appropriate cmake file under ``<TS_ROOT>/external/<name>``.
 
+Binaries of the ``Debug`` and ``DebugCoverage`` build types will have a suffix appended to their base name. This allows
+multiple binaries to coexist on the same system at the same time. However the system integrator can only select
+a single "release" build type.
+
+
 Building and Installing
 -----------------------
 When building from a clean environment where no generated build files exist, it is necessary to run
diff --git a/docs/developer/docs-build.rst b/docs/developer/docs-build.rst
index 9f36e64..3a11281 100644
--- a/docs/developer/docs-build.rst
+++ b/docs/developer/docs-build.rst
@@ -16,7 +16,7 @@
 
 - GNUMake
 - Python 3 (3.5 or later)
-- PlantUML (1.2017.15 or later)
+- PlantUML (1.2024.7 or later)
 
 You must also install the Python modules that are specified in the
 ``requirements.txt`` file in the root of the ``docs`` directory. These modules
@@ -28,7 +28,7 @@
 -------------------
 
 An example set of installation commands for Linux with the following assumptions:
-    #. OS and version: Ubuntu 18.04 LTS
+    #. OS and version: Ubuntu 22.04 LTS
     #. `virtualenv` is used to separate the python dependencies
     #. pip is used for python dependency management
     #. `bash` is used as the shell.
@@ -36,6 +36,7 @@
 .. code:: shell
 
     sudo apt install make python3 python3-pip virtualenv python3-virtualenv plantuml
+    wget https://github.com/plantuml/plantuml/releases/download/v1.2024.7/plantuml-1.2024.7.jar -O $HOME/plantuml.jar
     virtualenv -p python3 ~/sphinx-venv
     . ~/sphinx-venv/bin/activate
     pip3 install -r requirements.txt
@@ -56,6 +57,7 @@
 .. code:: shell
 
    . ~/sphinx-venv/bin/activate
+   export PLANTUML_JAR_PATH=$HOME/plantuml.jar
    make clean
    make
    deactivate
@@ -64,7 +66,33 @@
 
 ::
 
-   <tf-a CMF root>/docs/_build/html/
+   <TS root>/docs/_build
+
+Configuring the documentation build
+-----------------------------------
+
+The plantuml binary used during the documentation build can be controlled using
+the following environment variables:
+
+    - ``PLANTUML``: specifies the location of a wrapper script. This must be
+      executable and shall run plantuml.jar with all arguments passed over to
+      the tool. If set, will override other settings.
+
+    - ``PLANTUML_JAR_PATH``: full path to the plantuml.jar file to use. If set,
+      an internal wrapper will be used to call plantuml.
+    - ``JAVA_HOME``: used only is ``PLANTUML_JAR_PATH`` is set to specify the
+      JVM executable location to be used by the internal wrapper. The JVM
+      binary should be JAVA_HOME/bin/java.
+
+      If ``JAVA_HOME`` is not set, then ``java`` available from the ``PATH``
+      will be used. If the executable can not be found on the ``PATH`` the
+      build will fail.
+
+If no environment variable is set, then the default setting of
+``sphinxcontrib.plantuml`` will be used, which is to run a wrapper called
+``plantuml`` from the ``PATH``.
+
+Please find the configuration process implementation in `docs/conf.py``.
 
 --------------
 
diff --git a/docs/developer/index.rst b/docs/developer/index.rst
index 3204633..e6ba7ae 100644
--- a/docs/developer/index.rst
+++ b/docs/developer/index.rst
@@ -6,6 +6,7 @@
     :caption: Contents:
 
     arch-overview
+    supported-architectural-features
     project-structure
     service-deployment-model
     service-access-protocols
diff --git a/docs/developer/service-deployment-model.rst b/docs/developer/service-deployment-model.rst
index 9f79999..4e3879f 100644
--- a/docs/developer/service-deployment-model.rst
+++ b/docs/developer/service-deployment-model.rst
@@ -1,5 +1,6 @@
 Service Deployment Model
 ========================
+
 A goal of the Trusted Services project is to provide a toolbox of reusable service components
 that can be deployed across a wide range of platforms. The project structure promotes reuse by
 grouping related source files into subdirectories that represent reusable components. Components
@@ -11,20 +12,19 @@
 deployments parent are sub-directories concerned with building and deploying different
 applications. Applications can generally be classified as one of the following:
 
-  - Service providers
-  - Test suites
-  - Libraries
-  - Development support applications
+  - Service providers (e.g. psa-crypto)
+  - Test suites (e.g. ts-service-test)
+  - Libraries (e.g. libts)
+  - Development support applications (e.g. fwu-tool)
 
 This page is mainly concerned with describing the conventions used to enable service providers
 to be deployed in different environments, on different platforms and with different capabilities.
 The conventions aim to minimize build definition duplication between alternative deployments
 while offering sufficient flexibility to customize capabilities and support different platforms.
-The service deployment model borrows from a pattern used for deploying cloud services where There
-is a similar requirement for deployment flexibility.
 
 Ports and Adapters Architecture
 -------------------------------
+
 An application is decoupled from any particular environment via a set of interfaces that reflect
 the needs of the application. This model conforms to the ports and adapters architectural
 pattern that aims to avoid tight coupling between application components and any particular
@@ -52,6 +52,7 @@
 
 Service Deployment Structure
 ----------------------------
+
 By convention, the directory structure for service provider deployments reflects the layers in
 the ports and adapters architecture. The following dependency diagram illustrates the set of
 relationships that exist for a fully defined deployment:
@@ -70,32 +71,39 @@
   * - Build Component
     - Defines
     - Reuse Scope
-  * - Application
-    - | Set of components that form the core application to be deployed.
-    - | All deployments of the application.
-  * - Infra
-    - | The set of adapters that realize the ports that the application depends on.
+  * - Deployment
+    - | Represents an application. Examples: a service provider, demo application, test application,
+      | some tool.
+    - | -
+  * - Infrastructure
+    - | A specific set of SW components that realize the ports that the application depends on.
       | An infrastructure definition may depend on:
 
-        * Environment specific components.
         * Drivers that conform to a driver model.
-        * Platform specific drivers.
     - | Any deployment that uses the same infrastructure to support the application.
       | This will depend on how specific the infrastructure is.  An infrastructure
-      | definition may allow for some level of configurability to enable deployment
+      | definition may allow for some level of configurability to enable a deployment
       | to impose a particular build configuration. Where an infrastructure includes
       | adapters that use a well supported driver model (such as UEFI), the scope
       | for reuse is large.
-  * - Env
+  * - Environment
     - | The set of environment specific components that are common across all
       | deployments of an application for a particular environment.
     - | All deployments of the application into a specific environment. There is
       | scope to improve reuse of environment specific components across multiple
       | deployments.
-  * - Config
-    - | Build configuration variables together with a particular application, infra
-      | and env.
-    - | Depends on how specific the config is.
+  * - Configuration
+    - | Build configuration variables together with a particular application, infrastructure
+      | and environment. Represents a specific build of the application.
+    - | None.
+  * - Platform
+    - | A specific set of hardware drivers and target platform specific settings.
+      | A platform definition may depend on:
+
+            * Hardware driver ports defined by various components.
+            * Hardware specific resources.
+            * Target specific resource selection.
+    - | None.
 
 Deployment Directory Structure
 ------------------------------
@@ -112,12 +120,11 @@
 Configuration Definitions
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 To build a particular configuration of the block-storage service provider (in this case, one
-that uses flash storage on the N1SDP platform), use::
+that uses flash storage emulated with semihosting on the AEM FVP platform), use::
 
-  cd deployments/block-storage/config/n1sdp-flash
+  cd deployments/block-storage/config/semihosted-opteesp
   cmake -B build
-  cd build
-  make
+  cmake --build build
 
 The CMakeLists.txt file for the n1sdp-flash deployment of the block-storage service provider
 includes:
@@ -189,7 +196,7 @@
   platform
       |-- providers
               |--arm
-                  |-- corstone1000
+                  |-- Corstone1000
                   |-- fvp
                       |-- fvp_base_aemva
                       |-- fvp_base_revc-2xaemv8a
diff --git a/docs/developer/software-requirements.rst b/docs/developer/software-requirements.rst
index cbdf81a..f361e77 100644
--- a/docs/developer/software-requirements.rst
+++ b/docs/developer/software-requirements.rst
@@ -32,7 +32,7 @@
 .. _OP-TEE documentation: https://optee.readthedocs.io/en/latest/building/gits/build.html#step-4-get-the-toolchains
 .. _arm Developer: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads
 .. _CMake download page: https://cmake.org/files/v3.18/
-.. _`AEM FVP`: https://developer.arm.com/-/media/Files/downloads/ecosystem-models/FVP_Base_RevC-2xAEMvA_11.18_16_Linux64.tgz
+.. _`AEM FVP`: https://developer.arm.com/-/media/Files/downloads/ecosystem-models/FVP_Base_RevC-2xAEMvA_11.22_14_Linux64.tgz
 
 *Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.*
 
diff --git a/docs/developer/supported-architectural-features.rst b/docs/developer/supported-architectural-features.rst
new file mode 100644
index 0000000..b75c6da
--- /dev/null
+++ b/docs/developer/supported-architectural-features.rst
@@ -0,0 +1,85 @@
+Supported Architectural Features
+================================
+
+.. _branch_protection:
+
+Branch Protection
+-----------------
+
+Branch protection covers two architecture features for mitigating Return Oriented Programming (ROP) and Jump Oriented
+Programming (JOP) attacks. For generic overview of these features please see
+`Providing protection for complex software`_.
+
+Branch Protection related hardware features can not be controlled from S-EL0 and to enable these co-operation with
+components running at higher exception levels is needed. Please refer to the documentation of the these components for
+information on how to enable these HW features.
+
+Pointer Authentication (FEAT_PAUTH)
+'''''''''''''''''''''''''''''''''''
+
+Pointer Authentication (PAC) is an ARMv8.3 feature where the return address of each function is signed. The signature is
+calculated when the function is called and verified upon returning. This is to ensure the return address has not been
+tampered with.
+
+Branch Target Identification (FEAT_BTI)
+'''''''''''''''''''''''''''''''''''''''
+
+Branch Target Identification (BTI) is an ARMv8.5 feature which is used to guard against the execution of instructions
+that are not the intended target of an indirect branch.
+
+For raw-binary SPs the TS build system will will mark the executable regions with the BTI attribute in the SP manifest
+file. The SPMC implementation running the SP is required to support this memory attribute, or has to unconditionally
+enable BTI for all executable regions to get the feature working.
+
+Although GCC has BTI support since v9, no BTI enabled libraries are shipped with the current GNUARM releases. A possible
+workaround is to compile from source as described in the `FAQ section of the OP-TEE documentation`_.
+
+Configuring Branch Protection in the TS build system
+''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The feature can be controlled using the ``BRANCH_PROTECTION`` variable. This can be set e.g. on the cmake command line
+by passing ``-DBRANCH_PROTECTION=<value>``. The default value is ``unset``. Please refer to `GCC manual`_ for the
+detailed description of the values.
+
+.. list-table:: Supported values of ``BRANCH_PROTECTION``
+   :name: branch_protection_table
+   :header-rows: 1
+
+   * - Value
+     - GCC option
+     - FEAT_PAUTH
+     - FEAT_BTI
+   * - unset
+     -
+     - usually `N` (depends on how GCC is compiled)
+     - usually `N` (depends on how GCC is compiled)
+   * - 0
+     - "none"
+     - N
+     - N
+   * - 1
+     - "standard"
+     - Y
+     - Y
+   * - 2
+     - "pac-ret"
+     - Y
+     - N
+   * - 3
+     - "pac-ret+leaf"
+     - Y
+     - N
+   * - 4
+     - "bti"
+     - N
+     - Y
+
+--------------
+
+.. _`FAQ section of the OP-TEE documentation`: https://optee.readthedocs.io/en/stable/faq/faq.html#faq-gcc-bti
+.. _`Providing protection for complex software` : https://developer.arm.com/documentation/102433/0200
+.. _`GCC Manual`: https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/AArch64-Options.html
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/developer/uml/ServiceDeploymentDependencies.puml b/docs/developer/uml/ServiceDeploymentDependencies.puml
index 515a7c5..b49c11c 100644
--- a/docs/developer/uml/ServiceDeploymentDependencies.puml
+++ b/docs/developer/uml/ServiceDeploymentDependencies.puml
@@ -7,19 +7,18 @@
 
 @startuml
 
-package Deployment
-package Application
-package Infrastructure
-package Environment
-package Platform
-package BuildConfig
-package Adapter
+component Deployment
+component Infrastructure
+component Environment
+component Configuration
+component Adapter
+component Adapter as pl_adapter
+component Platform
 
-Deployment -down.> Application
 Deployment -down.> Infrastructure
 Deployment -down.> Environment
-Deployment -down.> "0..1" Platform
-Deployment -down.> "0..1" BuildConfig
+Deployment -down.> Configuration
+Deployment -down.> Platform
 Infrastructure -down.> "0..*" Adapter
-
+Platform -down.> "0..*" "pl_adapter"
 @enduml
\ No newline at end of file
diff --git a/docs/environments/secure-partitions/spm/optee/userspace-programs-on-fvp.rst b/docs/environments/secure-partitions/spm/optee/userspace-programs-on-fvp.rst
index f81e1df..aeb26fb 100644
--- a/docs/environments/secure-partitions/spm/optee/userspace-programs-on-fvp.rst
+++ b/docs/environments/secure-partitions/spm/optee/userspace-programs-on-fvp.rst
@@ -59,8 +59,7 @@
   # Install the shared library and executables
   cp -vat /usr out/ts-install/arm-linux/lib out/ts-install/arm-linux/bin
 
-  # Load the kernel modules
-  out/linux-arm-ffa-tee/load_module.sh
+  # Load the kernel module
   out/linux-arm-ffa-user/load_module.sh
 
   # Run the test application
diff --git a/docs/project/change-log.rst b/docs/project/change-log.rst
index 2db073a..a38d707 100644
--- a/docs/project/change-log.rst
+++ b/docs/project/change-log.rst
@@ -4,7 +4,7 @@
 This document contains a summary of the new features, changes, fixes and known issues in each release of Trusted
 Services.
 
-Version <next>
+Version v1.1.0
 --------------
 
 - Trustedfirmware.org has deprecated Phabricator, the wiki and issue tracking provider. This functionality has been
@@ -16,16 +16,34 @@
 ^^^^^^^^^^^^^^^^^^
 
 - Add documentation covering the :ref:`OP-TEE SPMC tests`.
-- Extend the :ref:`UEFI SMM Services` to support Authenticated Variables.
+- :ref:`UEFI SMM Services`:
+
+    - Extend the implementation to support Authenticated Variables.
+    - Relax the UEFI variable name length limit imposed by the size of the RPC buffer.
+
 - Introduce a work in progress RPMB implementation and integrate it to the Block Storage service. The current
   configuration uses an SWd RAM buffer for data storage, and is not connected to the RPMB provider running in the NWd.
   This is the first baseline to implement a scenario where the RPMB owner is an S-EL0 SP.
 - Introduce the :ref:`Logging Service`.
 - Add crypto key store partitioning support to the Crypto Service. This feature allows isolating clients running in
   different SPs.
-- Add the "RSS Com" protocol. RSS Com is a new protocol used between secure partitions and security subsystems like the
-  Secure Enclave on Corstone-1000 or RSS on Kronos.
+- Add the "RSE Com" protocol. RSE Com is a new protocol used between secure partitions and security subsystems like the
+  Secure Enclave on Corstone-1000 or Runtime Security Engine on `RD-1 AE`_.
+- libsp learnt to support FF-A v1.1 and all SPs are updated to use this version.
+- tstee Linux driver was merged upstream and the LinuxFfaTEEDriver external component is removed.
+- All SP and arm-linux deployments are updated to support Armv8.5-A Branch Protection feature.
+  See: :ref:`branch_protection`
+- A new FWU agent implementation is introduced, which implements a `PSA Certified Firmware Update API 1.0`_ client. This
+  component can be used to implement an FWU proxy on A+M systems like Corstone1000 and RD-1 AE. For more details see:
+  :ref:`Firmware update on A+M systems`
+- A new shared library called ``libpsats`` is introduced to help integration of PSA clients to 3rd party linux
+  user-space projects. For details see: :ref:`libs-libpsats`
+- The following new tests and enhancements have been added to :ref:`OP-TEE SPMC tests`:
 
+    - FFA_MEM_PERM_GET/SET tests.
+    - Memory sharing test updated to cover invalid requests.
+    - VM availability message tests.
+    - Endpoint ID checking is fixed.
 
 Deprecations
 ^^^^^^^^^^^^
@@ -36,12 +54,14 @@
 Updated external components
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-- MbedTLS version int the Crypto service is updated to v3.5.1.
+- MbedTLS version in the Crypto service is updated to v3.6.0.
 - NanoPB has been upgraded to v0.4.8.
+- Newlib is no longer required and the newlib external component is removed.
 
 Breaking changes
 ^^^^^^^^^^^^^^^^
 
+None.
 
 Resolved issues
 ^^^^^^^^^^^^^^^
@@ -53,10 +73,7 @@
 Known limitations
 ^^^^^^^^^^^^^^^^^
 
-- UEFI private variable authentication is not implemented in an UEFI compliant way. Currently such variables are
-  authenticated by the certificates stored on the `DB` variable which is incorrect. Instead an implementation defined
-  variable should be used to store the needed certificates. The plan is to follow ``EDK2`` use ``certdb`` and
-  ``certdbv`` variables for this purpose.
+None.
 
 Version 1.0.0
 -------------
@@ -95,10 +112,12 @@
     - Remove the encoding type entity and use service UUIDs to represent the serialization type.
     - Service property discovery is to be implemented in the future.
 
-- Add support for the Corstone-1000 platform. For more information about this platform please see: `Corstone-1000 product homepage`_
+- Add support for the Corstone-1000 platform. For more information about this platform please see:
+  `Corstone-1000 product homepage`_
 
-- SPs now indicate support of :term:`Normal World` interrupt preemption capability in their SP manifest and allow the SPMC to enable
-  preemption if possible. This removes NWd interrupts being disabled for long periods due to long service calls.
+- SPs now indicate support of :term:`Normal World` interrupt preemption capability in their SP manifest and allow the
+  SPMC to enable preemption if possible. This removes NWd interrupts being disabled for long periods due to long service
+  calls.
 
 - Add support for the Armv8-A CRC32 feature for :term:`Secure World` and :term:`Normal World` components.
 
@@ -155,8 +174,9 @@
   - Initial Attestation
   - Smm Variable
 
-Services may be accessed using client components that implement "`Psacertified v1.0 APIs`_". The project includes deployments
-that integrate `PSA API certification tests`_ with API clients to facilitate end-to-end PSA certification testing.
+Services may be accessed using client components that implement "`Psacertified v1.0 APIs`_". The project includes
+deployments that integrate `PSA API certification tests`_ with API clients to facilitate end-to-end PSA certification
+testing.
 
 Known limitations
 '''''''''''''''''
@@ -178,8 +198,8 @@
 Supported Integration Systems
 '''''''''''''''''''''''''''''
 
-The reference solution uses the OP-TEE integration methodology. This relies on the google repo tool for high-level dependency
-management and a set of makefiles to capture the build configuration information. For details please refer to
+The reference solution uses the OP-TEE integration methodology. This relies on the google repo tool for high-level
+dependency management and a set of makefiles to capture the build configuration information. For details please refer to
 `OP-TEE git repo documentation`_.
 
 The project is officially enabled in `Yocto meta-arm`_.
@@ -201,18 +221,19 @@
 
 --------------
 
-.. _`FF-A Specification v1.0`: https://developer.arm.com/documentation/den0077/a
+.. _`FF-A Specification v1.1`: https://developer.arm.com/documentation/den0077/e
 .. _`Psacertified v1.0 APIs`: https://www.psacertified.org/development-resources/building-in-security/specifications-implementations/
 .. _`OP-TEE v3.19`: https://github.com/OP-TEE/optee_os/tree/3.19.0
 .. _`Yocto meta-arm` : https://gitlab.oss.arm.com/engineering/yocto/meta-arm/-/tree/master/meta-arm/recipes-security/trusted-services
 .. _`project wiki`: https://github.com/Trusted-Services/trusted-services/wiki/Trusted-Services-test-reports
-.. _`AEM FVP`: https://developer.arm.com/-/media/Files/downloads/ecosystem-models/FVP_Base_RevC-2xAEMvA_11.18_16_Linux64.tgz
+.. _`AEM FVP`: https://developer.arm.com/-/media/Files/downloads/ecosystem-models/FVP_Base_RevC-2xAEMvA_11.22_14_Linux64.tgz
 .. _`PSA API certification tests`: https://github.com/ARM-software/psa-arch-tests
 .. _`OP-TEE git repo documentation`: https://optee.readthedocs.io/en/latest/building/gits/build.html
 .. _`Corstone-1000 product homepage`: https://developer.arm.com/Processors/Corstone-1000
 .. _`Arm FWU-A specification`: https://developer.arm.com/documentation/den0118
 .. _`Trusted Services organization`: https://github.com/Trusted-Services
-
+.. _`RD-1 AE`: https://developer.arm.com/Tools%20and%20Software/Arm%20Reference%20Design-1%20AE
+.. _`PSA Certified Firmware Update API 1.0`: https://arm-software.github.io/psa-api/fwu/1.0/
 
 *Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.*
 
diff --git a/docs/project/contributing.rst b/docs/project/contributing.rst
index 5d8cb8f..1576df0 100644
--- a/docs/project/contributing.rst
+++ b/docs/project/contributing.rst
@@ -9,39 +9,46 @@
 Getting Started
 ---------------
 
-- Make sure you have a GitHub account and you are logged on `developer.trustedfirmware.org`_.
-- Send an email to the |TS_MAIL_LIST| about your work. This gives everyone
-  visibility of whether others are working on something similar.
+- Make sure you have a GitHub account and you are logged in at `review.trustedfirmware.org`_.
+- Make sure the following is configured in `Gerrit settings`_:
+
+    - Your public key is set under ``SSH Keys``. This will be needed when pushing changes.
+      Please see `Public keys section`_ of Gerrit documentation if you need new keys.
+    - The email address you will use in git is added under ``Email Addresses``.
+
 - Clone the |TS_REPO| on your own machine.
 
 Making Changes
 --------------
 
+- Send an email to the |TS_MAIL_LIST| about your work. This gives everyone visibility of whether others are working on
+  something similar.
 - Make commits of logical units. See these general `Git guidelines`_ for contributing to a project.
 - Follow the :ref:`Coding Style & Guidelines`.
 - Keep the commits on topic. If you need to fix another bug or make another enhancement, please create a separate
   change.
 - Avoid long commit series. If you do have a long series, consider whether some
   commits should be squashed together or addressed in a separate topic.
-- Make sure your commit messages are in the proper format. Please keel the 50/72 rule (for details see `Tim Popes blog entry`_.)
+- Make sure your commit messages are in the proper format. Please keep the 50/72 rule (for details see
+  `Tim Popes blog entry`_.)
 - Where appropriate, please update the documentation.
 
    - Consider which documents or other in-source documentation needs updating.
-   - Ensure that each changed file has the correct copyright and license information. Files that entirely consist of
-     contributions to this project should have a copyright notice and BSD-3-Clause SPDX license identifier of the form
-     as shown in :ref:`license`. Example copyright and license comment blocks are shown in :ref:`Coding Style & Guidelines`.
-     Files that contain changes to imported Third Party IP files should retain their original copyright and license
-     notices. For significant contributions you may add your own copyright notice in following format::
+   - For topics with multiple commits, you should make all documentation changes (and nothing else) in the last commit
+     of the series. Otherwise, include the documentation changes within the single commit.
+
+- Ensure that files have the correct copyright and license information. Files that entirely consist of contributions to
+  this project should have a copyright notice and BSD-3-Clause SPDX license identifier of the form as shown in
+  :ref:`license`. Example copyright and license comment blocks are shown in :ref:`Coding Style & Guidelines`. Files that
+  contain changes to imported Third Party IP files should retain their original copyright and license
+  notices. For significant contributions you may add your own copyright notice in following format::
 
         Portions copyright (c) [XXXX-]YYYY, <OWNER>. All rights reserved.
 
-     where XXXX is the year of first contribution (if different to YYYY) and YYYY is the year of most recent
-     contribution. *<OWNER>* is your name or your company name.
-   - For any change, ensure that YYYY is updated if a contribution is made in a year more recent than the previous YYYY.
-   - If you are submitting new files that you intend to be the technical sub-maintainer for (for example, a new platform
-     port), then also update the :ref:`maintainers` file.
-   - For topics with multiple commits, you should make all documentation changes (and nothing else) in the last commit
-     of the series. Otherwise, include the documentation changes within the single commit.
+  where `XXXX` is the year of first contribution (if different to `YYYY`) and `YYYY` is the year of most recent
+  contribution. `<OWNER>` is your name or your company name.
+- If you are submitting new files that you intend to be the technical sub-maintainer for (for example, a new platform
+  port), then also update the :ref:`maintainers` file.
 
 - Please test your changes.
 
@@ -54,37 +61,46 @@
   contribution is made under the terms of the :download:`Developer Certificate of Origin <../../dco.txt>`.
 
   More details may be found in the `Gerrit Signed-off-by Lines guidelines`_.
-
 - Ensure that each commit also has a unique ``Change-Id:`` line. If you have cloned the repository with the "`Clone with
   commit-msg hook`" clone method, this should already be the case.
 
   More details may be found in the `Gerrit Change-Ids documentation`_.
 
-- Submit your changes for review at https://review.trustedfirmware.org targeting the ``integration`` branch.
+- Select your target branch.
 
-  - The changes will then undergo further review and testing by the :ref:`maintainers`. Any review comments will be made
-    directly on your patch. This may require you to do some rework.
+    - If all commits of your change compile and run ok, then your review can target the ``integration`` branch.
+    - If not, a topic branch is needed. The name of the topic branch has to be kept reasonably sort and has to follow
+      this format: ``topics/<user-id>/<topic>``.
 
-  Refer to the `Gerrit Uploading Changes documentation`_ for more details.
+        - `user-id` is unique ID of the user (e.g. nick name, <first name>_<last name>, etc...).
+        - `topic` is a title reflecting the purpose of the change.
+- Push your changes to Gerrit. Refer to the `Gerrit Uploading Changes documentation`_ to see how this can be done.
+
+- The changes will then undergo further review and testing by the :ref:`maintainers`. Any review comments will be made
+  directly on your patch. This may require you to do some rework.
 
 - When the changes are accepted, the :ref:`maintainers` will integrate them.
 
-  - Typically, the :ref:`maintainers` will merge the changes into the ``integration`` branch.
-  - If the changes are not based on a sufficiently-recent commit, or if they cannot be automatically rebased, then the
-    :ref:`maintainers` may rebase it on the ``main`` branch or ask you to do so.
-  - After final integration testing, the changes will make their way into the ``main`` branch. If a problem is found
-    during integration, the merge commit will be removed from the ``integration`` branch and the :ref:`maintainers` will
-    ask you to create a new patch set to resolve the problem.
+- Typically, the :ref:`maintainers` will merge the changes into the target branch.
+
+- If the changes are not based on a sufficiently-recent commit, or if they cannot be automatically rebased, then the
+  :ref:`maintainers` may rebase it ask you to do so.
+
+- After final integration testing, the changes will make their way into the ``main`` branch. If a problem is found
+  during integration, the merge commit will be removed from the ``integration`` branch and the :ref:`maintainers` will
+  ask you to create a new patch set to resolve the problem.
 
 --------------
 
-.. _developer.trustedfirmware.org: https://developer.trustedfirmware.org
+.. _review.trustedfirmware.org: https://review.trustedfirmware.org
 .. _Git guidelines: http://git-scm.com/book/ch5-2.html
 .. _Gerrit Uploading Changes documentation: https://review.trustedfirmware.org/Documentation/user-upload.html
 .. _Gerrit Signed-off-by Lines guidelines: https://review.trustedfirmware.org/Documentation/user-signedoffby.html
 .. _Gerrit Change-Ids documentation: https://review.trustedfirmware.org/Documentation/user-changeid.html
 .. _`Tim Popes blog entry`: https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
-.. _`Trusted Firmware Security Center`: https://developer.trustedfirmware.org/w/collaboration/security_center/
+.. _`Trusted Firmware Security Center`: https://trusted-firmware-docs.readthedocs.io/en/latest/security_center/index.html
+.. _`Gerrit settings`: https://review.trustedfirmware.org/settings/
+.. _`Public keys section`: https://review.trustedfirmware.org/Documentation/user-upload.html#configure_ssh_public_keys
 
 *Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.*
 
diff --git a/docs/project/maintainers.rst b/docs/project/maintainers.rst
index 992d926..307f93e 100644
--- a/docs/project/maintainers.rst
+++ b/docs/project/maintainers.rst
@@ -16,8 +16,6 @@
 ----------------
 :M: Dan Handley <dan.handley@arm.com>
 :G: `danh-arm`_
-:M: Miklós Bálint <miklos.balint@arm.com>
-:G: `wmnt`_
 :M: György Szing <gyorgy.szing@arm.com>
 :G: `gyuri-szing`_
 :L: |TS_MAIL_LIST|
@@ -25,8 +23,6 @@
 Code owners
 --------------------
 
-:M: Julian Hall <julian.hall@arm.com>
-:G: `julianhall-arm`_
 :M: Bálint Dobszay <balint.dobszai@arm.com>
 :G: `balintdobszay`_
 :M: Imre Kis <imre.kis@arm.com>
@@ -36,14 +32,12 @@
 --------------
 
 .. _danh-arm: https://github.com/danh-arm
-.. _wmnt: https://github.com/wmnt
 .. _gyuri-szing: https://github.com/gyuri-szing
 .. _balintdobszay: https://github.com/balintdobszay
-.. _julianhall-arm: https://github.com/julianhall-arm
 .. _imre-kis-arm: https://github.com/imre-kis-arm
 
 .. _`Linux Maintainers file`: https://github.com/torvalds/linux/blob/master/MAINTAINERS#L80
-.. _Project Maintenance Process: https://developer.trustedfirmware.org/w/collaboration/project-maintenance-process/
+.. _Project Maintenance Process: https://trusted-firmware-docs.readthedocs.io/en/latest/generic_processes/project_maintenance_process.html
 
 *Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved.*
 
diff --git a/docs/project/quality-assurance/verification-methodology.rst b/docs/project/quality-assurance/verification-methodology.rst
index f68401d..3dedf00 100644
--- a/docs/project/quality-assurance/verification-methodology.rst
+++ b/docs/project/quality-assurance/verification-methodology.rst
@@ -19,7 +19,8 @@
   - spelling mistakes
   - git commit message formatting
 
-Please find the configuration of this tool in the :download:`TS repository.<../../../.checkpatch>`
+Please find the configuration of this tool in the :download:`TS repository.<../../../.checkpatch>` but do not forget
+to set ``CODESPELL_FILE`` variable in the environment to the local copy of the `codespell dictionary v2.3.0`_.
 
 Cppcheck tool
 '''''''''''''
@@ -61,10 +62,31 @@
 The project hosts deployment helping compliance testing. For more information please refer to
 :ref:`Platform Certification`.
 
+Measuring Quality of testing
+''''''''''''''''''''''''''''
+
+The primary metric to measure runtime testing quality is code coverage. The project uses two methods to measure code
+coverage:
+
+    - "Host side" coverage measurement, where code coverage is measured using Unit Tests and Component Test executed on
+      the build host.
+
+      The measurement relies on GCCs `-ftest-coverage` compilation switch and the lcov tool. In order to include
+      coverage data of PSA client code and of service providers, `libpsats` and `libts` have to be built using
+      the `DebugCoverage` build type. If the build type override is not used, the build system will automatically build
+      and use the appropriate binaries.
+
+    - Coverage measurement on the target. This feature is only supported by the :ref:`AEM FVP` platform and uses
+      `qa-tools`_.
+
+Coverage measurement is automated in the CI, which is not publicly accessible yet.
+
 ------------------
 
 .. _`Checkpatch`: https://docs.kernel.org/dev-tools/checkpatch.html
 .. _`CppCheck`: https://cppcheck.sourceforge.io/
+.. _`codespell dictionary v2.3.0`: https://raw.githubusercontent.com/codespell-project/codespell/v2.3.0/codespell_lib/data/dictionary.txt
+.. _`qa-tools`: https://gitlab.arm.com/tooling/qa-tools
 
 *Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.*
 
diff --git a/docs/project/versioning_policy.rst b/docs/project/versioning_policy.rst
index c176db3..c3a5503 100644
--- a/docs/project/versioning_policy.rst
+++ b/docs/project/versioning_policy.rst
@@ -29,7 +29,8 @@
 
 The project hosts multiple components which can be used separately and thus need
 compatibility information expressed independently. Such components get a
-dedicated version ID. Examples are :ref:`libs-libsp` and :ref:`libs-libts`.
+dedicated version ID. Examples are :ref:`libs-libsp` :ref:`libs-libts` and
+:ref:`libs-libpsats`.
 
 Components are never released standalone but only part of a TS release. In that
 sense a set of independent component version IDs are assigned to a TS release ID.
diff --git a/docs/quickstart/optee-testing.rst b/docs/quickstart/optee-testing.rst
index 7eccf7a..9ff2421 100644
--- a/docs/quickstart/optee-testing.rst
+++ b/docs/quickstart/optee-testing.rst
@@ -47,7 +47,6 @@
 
   cd /mnt/host
   cp -vat /usr out/ts-install/arm-linux/lib out/ts-install/arm-linux/bin
-  out/linux-arm-ffa-tee/load_module.sh
   out/linux-arm-ffa-user/load_module.sh
   ts-service-test -v
 
diff --git a/docs/quickstart/pc-testing.rst b/docs/quickstart/pc-testing.rst
index 295273d..7cace20 100644
--- a/docs/quickstart/pc-testing.rst
+++ b/docs/quickstart/pc-testing.rst
@@ -36,7 +36,7 @@
 
   cmake -B build-ts -S deployments/ts-service-test/linux-pc
   make -C build-ts install
-  LD_PRELOAD=build-ts/install/linux-pc/lib/libts.so build-ts/install/linux-pc/bin/ts-service-test -v
+  LD_LIBRARY_PATH=build-ts/install/linux-pc/lib build-ts/install/linux-pc/bin/ts-service-test -v
 
 Build and run *psa-api-test*
 ----------------------------
@@ -51,7 +51,7 @@
 
   cmake -B build-pa deployments/psa-api-test/crypto/linux-pc
   make -C build-pa install
-  LD_PRELOAD=build-pa/install/linux-pc/lib/libts.so build-pa/install/linux-pc/bin/psa-crypto-api-test
+  LD_LIBRARY_PATH=build-ts/install/linux-pc/lib build-pa/install/linux-pc/bin/psa-crypto-api-test
 
 psa-api test binaries accept the listed command-line arguments:
 
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 516a46c..a68d704 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -6,9 +6,10 @@
 
 # Python dependencies for building the documentation.
 
-Sphinx==4.5
-sphinx-rtd-theme==1.0.0
-sphinxcontrib-moderncmakedomain==3.21.4
-sphinxcontrib-plantuml==0.23
 Jinja2==2.11.3
-markupsafe==2.0.1
+MarkupSafe==2.0.1
+setuptools==75.2.0
+Sphinx==5.1.1
+sphinx-rtd-theme==2.0.0
+sphinxcontrib-moderncmakedomain==3.29.0
+sphinxcontrib-plantuml==0.30
diff --git a/docs/services/fwu/fwu-service-description.rst b/docs/services/fwu/fwu-service-description.rst
index 0fbc384..30e4d57 100644
--- a/docs/services/fwu/fwu-service-description.rst
+++ b/docs/services/fwu/fwu-service-description.rst
@@ -358,7 +358,7 @@
 
 Each installer is assigned a location ID to bind the installer to a particular firmware location.
 Location IDs are integer values defined by the configuration code. For example, where firmware
-consists of AP firmware, SCP firmware and RSS firmware, location IDs could be assigned as follows:
+consists of AP firmware, SCP firmware and RSE firmware, location IDs could be assigned as follows:
 
 .. list-table::
   :header-rows: 1
@@ -369,7 +369,7 @@
     - 0
   * - SCP firmware
     - 1
-  * - RSS firmware
+  * - RSE firmware
     - 2
 
 When volume objects are added to the volume index, each one is assigned a volume ID which is
@@ -415,7 +415,7 @@
 
   - **AP Firmware** - where application firmware is contained within a FIP
   - **SCP Firmware** - binary boot image for SCP
-  - **RSS Firmware** - binary boot image for RSS
+  - **RSE Firmware** - binary boot image for RSE
 
 The GPT based configurator relies on access to the GPT partition table. During initialization
 of the Update Agent, the configurator iterates over each partition entry. If no installers are
diff --git a/docs/services/fwu/index.rst b/docs/services/fwu/index.rst
index 8042445..4a7786a 100644
--- a/docs/services/fwu/index.rst
+++ b/docs/services/fwu/index.rst
@@ -7,9 +7,10 @@
 
     fwu-service-description
     fwu-gpt-disk-image
+    psa-fwu-m
 
 --------------
 
-*Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.*
+*Copyright (c) 2023-2024, Arm Limited and Contributors. All rights reserved.*
 
 SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/services/fwu/psa-fwu-m.rst b/docs/services/fwu/psa-fwu-m.rst
new file mode 100644
index 0000000..26ffed0
--- /dev/null
+++ b/docs/services/fwu/psa-fwu-m.rst
@@ -0,0 +1,168 @@
+Firmware update on A+M systems
+------------------------------
+
+Concept
+'''''''
+
+Some platforms have both Cortex-A and Cortex-M subsystems and implement the PSA RoT on the M class core. On such systems
+the firmware store is usually read-only or not accessible to the Cortex-A cores due to security reasons. In such cases
+it may still be beneficial to implement the cloud update client on the Cortex-A subsystem, and a solution is needed to
+bridge the Cortex-A and the Cortex-M firmware update implementations. For this purpose TS implements a special firmware
+update agent which is documented below.
+
+.. figure:: ../image/psa-fwu-m-block.svg
+
+   Components on an A+M system.
+
+Standards and specifications
+''''''''''''''''''''''''''''
+
+* `Platform Security Firmware Update for the A-profile Arm Architecture`_ (A class FWU specification)
+* `PSA Certified Firmware Update API 1.0`_ (M class FWU specification)
+* `Trusted Firmware-M FWU service`_
+
+Update agent implementation
+'''''''''''''''''''''''''''
+
+The update agent implements the `Platform Security Firmware Update for the A-profile Arm Architecture`_ API (prefixed
+with ``fwu_``) and acts as a `PSA Certified Firmware Update API 1.0`_ client (prefixed with ``psa_fwu_``). The update
+agent has to align the slightly different APIs by maintaining an internal registry of image states and image handles.
+The differences between the two firmware update protocols are:
+
+* `Platform Security Firmware Update for the A-profile Arm Architecture`_ identifies images by UUID while
+  `PSA Certified Firmware Update API 1.0`_ identifies component by an 8 bit component ID.
+* Although similar calls are implemented, FWU-A operates on images, while FWU-M on the whole image set.
+* There is no *image handle* concept in `PSA Certified Firmware Update API 1.0`_
+* Differences in the returned details of the image query functions
+
+The solutions to these differences:
+
+* A static UUID to component ID mapping is used. This has to be passed to the agent init function.
+* Gathering per image based calls and then make the actual call to the M class side when the operation was called on
+  each image.
+* Implement internal image handle registry.
+* Convert the image query result returned by FWU-M to FWU-A format. There are similar field, but this imposes some
+  limitations.
+
+
+``fwu_discover()``
+``````````````````
+
+This function returns the list of implemented features.
+
+``fwu_begin_staging()``
+```````````````````````
+
+Clients can only write images in staging state. In order to switch to staging state, the client must call
+``fwu_begin_staging()``. This results in ``psa_fwu_start()`` calls on all selected images. The client can pass a list of
+the selected image UUIDs or select all images for staging.
+
+If the agent is already in staging state when ``fwu_begin_staging()`` is called, then the agent first discards all
+transient state by calling ``fwu_cancel_staging()`` and ``psa_fwu_clean()`` on all image.
+
+.. uml:: ../uml/psa_fwu_m_update_agent/fwu_begin_staging.puml
+
+``fwu_end_staging()``
+`````````````````````
+
+Finishes the staging state when all images that were selected for the update have been updated. If all selected images
+are also accepted the agent switches to regular state and the update is completed. If there are not accepted images, the
+agent switches to trial state, so the client can validate the new set of images and accept or reject them.
+
+On calling ``fwu_end_staging()`` the agent calls ``psa_fwu_finish()`` on each selected image, then calls
+``psa_fwu_install()``. If all images have been accepted (see ``fwu_commit()``) it also calls ``psa_fwu_accept()``.
+
+.. uml:: ../uml/psa_fwu_m_update_agent/fwu_end_staging.puml
+
+``fwu_cancel_staging()``
+````````````````````````
+
+Cancels staging state and reverts to original regular state. The function calls ``psa_fwu_cancel()`` on each selected
+image.
+
+.. uml:: ../uml/psa_fwu_m_update_agent/fwu_cancel_staging.puml
+
+``fwu_open()``
+``````````````
+
+`Platform Security Firmware Update for the A-profile Arm Architecture`_ has a concept of image handles. An image can be
+opened via ``fwu_open()``, then accessed by calling ``fwu_write_stream()`` or ``fwu_read_stream()``, and finally it can
+be closed by invoking ``fwu_commit()``. However `PSA Certified Firmware Update API 1.0`_ does not have a similar concept
+and once the staging process was started for an image by calling ``psa_fwu_start()``, the image can be written through
+``psa_fwu_write()``.
+
+The update agent provides an internal registry of opened images and their access rights so it can handle subsequent
+calls on the image handle. The open call can open an image for either write or read operations but not for both. The
+image is identified by its UUID. Only images which were selected for staging can be opened for write.
+
+There is no actual call made to the M class side on opening a image.
+
+`PSA Certified Firmware Update API 1.0`_ does not provide a function for reading images, so opening images will fail
+except for opening the image directory. Only the image directory supports read operations.
+
+``fwu_write_stream()``
+``````````````````````
+
+This function writes data into the opened image. The image handle has to be opened for write operations. The agent calls
+``psa_fwu_write()`` for doing the actual write and the write offset is tracked internally.
+
+``fwu_read_stream()``
+`````````````````````
+
+This function read data from the opened image. The image handle has to be opened for read operations.
+
+This call is only implemented for the image directory which returns the available image list as specified in
+`Platform Security Firmware Update for the A-profile Arm Architecture`_. It does not support the partial reading of the
+image directory.
+
+``fwu_commit()``
+````````````````
+
+The commit call closes the image handle. The client can also mark the image as accepted on commit and this the method
+for accepting all images before calling ``fwu_end_staging()``.
+
+There is no actual call made to the M class side on comiting an image.
+
+``fwu_accept_image()``
+``````````````````````
+
+`PSA Certified Firmware Update API 1.0`_ only provides a ``psa_fwu_accept()`` function which accepts the whole set of
+selected images. In order to align with the ``fwu_accept_image()`` API, it only marks the given image as accepted and
+calls ``psa_fwu_accept()`` when all images have been accepted. This results in a state transition to regular state.
+
+.. uml:: ../uml/psa_fwu_m_update_agent/fwu_accept.puml
+
+``fwu_select_previous()``
+`````````````````````````
+
+Selects previous working state (i.e. rejects the firmware update) and transitions back to regular state after calling
+``psa_fwu_reject()``.
+
+.. uml:: ../uml/psa_fwu_m_update_agent/fwu_select_previous.puml
+
+Image directory
+'''''''''''''''
+
+The client can read the image directory by opening and reading an image with dedicated UUID
+(``deee58d9-5147-4ad3-a290-77666e2341a5``). On image directory read, the agent will call ``psa_fwu_query()`` on each
+image and convert the value of similar fields.
+
+* The UUID is based on the UUID - component ID mapping passed upon agent initialization.
+* The images only support write operation due to FWU-M limitation.
+* The image maximal size is copied from the component info structure.
+* The lowest accepted version is set to 0.
+* The image version is converted from the fields of the component info structure into a single 32 bit value. The build
+  field is dropped due to lack of space in the 32 bit field.
+* The images is marked accepted if its state in the component info structure is ``PSA_FWU_UPDATED``.
+
+.. uml:: ../uml/psa_fwu_m_update_agent/image_directory.puml
+
+--------------
+
+.. _`Platform Security Firmware Update for the A-profile Arm Architecture`: https://developer.arm.com/documentation/den0118/latest/
+.. _`PSA Certified Firmware Update API 1.0`: https://arm-software.github.io/psa-api/fwu/1.0/
+.. _`Trusted Firmware-M FWU service`: https://tf-m-user-guide.trustedfirmware.org/design_docs/services/tfm_fwu_service.html
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
diff --git a/docs/services/image/gpt-based-flash-layout.svg b/docs/services/image/gpt-based-flash-layout.svg
index 8f1061c..04869eb 100644
--- a/docs/services/image/gpt-based-flash-layout.svg
+++ b/docs/services/image/gpt-based-flash-layout.svg
@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Do not edit this file with editors other than diagrams.net -->
+<!-- Do not edit this file with editors other than draw.io -->
 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="401px" height="781px" viewBox="-0.5 -0.5 401 781" content="&lt;mxfile host=&quot;confluence.arm.com&quot; modified=&quot;2023-02-16T09:50:57.516Z&quot; agent=&quot;5.0 (X11)&quot; etag=&quot;9oA7HNylA2Pn-M09WDsz&quot; version=&quot;20.3.7&quot; type=&quot;atlas&quot;&gt;&lt;mxAtlasLibraries/&gt;&lt;diagram id=&quot;MJao7NBNlqcqI8fyxszN&quot; name=&quot;Page-1&quot;&gt;7Zlbb9owGIZ/TS4tJfEB57LQwqqpHSLtql06sQNZkxgZM2C/fg6YEpZsgo0oakW4wH59iP0+/pBtHDjI1yPF5rMHyUXm+C5fO/DW8X0PQ2i+SmVjFRjgnTJVKbfaQQjTn8KKrlWXKReLo4paykyn82MxlkUhYn2kMaXk6rhaIrPjt87Z1L7RPQhhzDJRq/aScj3bqRRXan8S6XS2f7Pn2pKc7StbYTFjXK4qErxz4EBJqXepfD0QWene3pddu+EfSt8GpkShT2kA5UA9jb49DvjjZC7zBz9ffAe2lx8sW9oJj5XUxsj0hzD6Q39iB683e0eUXBZclJ26DuyvZqkW4ZzFZenKLAKjzXSemZxnkkmaZQOZSbVtCxMaizg2+kIr+SoqJRHFCJcd1qe1H6NQWqwrkp3mSMhcaLUxVWwpoNbyzW/51YEg2nOaVehBqzG7aKZvXR98NQlr7Rk2+w02pznbDno0frqsx7j8NHlMtk/ZQha6ou+elrzHJ3pP2vIe/sX74ctzucqFZpxp5vgkM6PpR8qkpmVqzJROdSoLU+tpMy9DYvR8f+vAG1OD5SWIIlqUX5T1GEXMBRTSHkBuQgCLkAcYjQKGGXG5Dy+LOUn85lDiJCKYtIPT65omqtE01t3cjMEwVfnKTPV/IPoIezEnAgRuIgCKPAyixHMBI0EUC58jRMlFIXIsKEdNEKkfQdISxF7XEHENoneFeG4kwq4pksZQDAeXwUgCzxjLIPB7JUbPRSBinIMehkHsuixw9zvJ940x6BpjrzEYrxjPwuh3vs2hjdE4CcOLYIwDRJmHCcA0jgCKIQURcgkQxI3MRsQvff8AGGHn+5ugMRqvGM/D2PkOZ7+OKhyf74b34CtTKYsysbisy0zQpPEsQGIqoqQdl9GpOxDcmsv164svocl/FqooL6Lev8Wn3ly0Z3H9+Dwpr6zM2Tn8AAbj7tdw/UTbZ/Hrcn69nvgHnKfGS3s//PWz7RvOj33TR1B73pvs4aJ8W1b5vwHe/QI=&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><rect x="0" y="0" width="400" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 15px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Protective MBR</div></div></div></foreignObject><text x="200" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Protective MBR</text></switch></g><rect x="0" y="30" width="400" height="60" fill="#f5f5f5" stroke="#666666" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 60px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #333333; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Primary GPT</div></div></div></foreignObject><text x="200" y="64" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">Primary GPT</text></switch></g><rect x="0" y="90" width="400" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 120px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Primary FWU Metadata<br />Partition Type GUID: 8a7a84a0-8387-40f6-ab41-a8b9a5a60d23</div></div></div></foreignObject><text x="200" y="124" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Primary FWU Metadata...</text></switch></g><rect x="0" y="150" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 180px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:AP-Firmware<br />Partition Type GUID: 2451cd6e-90fe-4b15-bf10-a69bce2d4486</div></div></div></foreignObject><text x="200" y="184" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">0:AP-Firmware...</text></switch></g><rect x="0" y="210" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 240px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:AP-Firmware<br />Partition Type GUID: 2451cd6e-90fe-4b15-bf10-a69bce2d4486</div></div></div></foreignObject><text x="200" y="244" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1:AP-Firmware...</text></switch></g><rect x="0" y="270" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 300px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:SCP-Firmware<br />Partition Type GUID: 691d5ea3-27fe-4104-badd-7539c00a9095</div></div></div></foreignObject><text x="200" y="304" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">0:SCP-Firmware...</text></switch></g><rect x="0" y="330" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 360px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:SCP-Firmware<br />Partition Type GUID: 691d5ea3-27fe-4104-badd-7539c00a9095</div></div></div></foreignObject><text x="200" y="364" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1:SCP-Firmware...</text></switch></g><rect x="0" y="390" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 420px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:RSS-Firmware<br />Partition Type GUID: c948a156-58cb-4c38-b406-e60bff2223d5</div></div></div></foreignObject><text x="200" y="424" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">0:RSS-Firmware...</text></switch></g><rect x="0" y="450" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 480px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:RSS-Firmware<br />Partition Type GUID: c948a156-58cb-4c38-b406-e60bff2223d5</div></div></div></foreignObject><text x="200" y="484" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">1:RSS-Firmware...</text></switch></g><rect x="0" y="510" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 535px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">UEFI-Variables</div></div></div></foreignObject><text x="200" y="539" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">UEFI-Variables</text></switch></g><rect x="0" y="560" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 585px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">OS Kernel</div></div></div></foreignObject><text x="200" y="589" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">OS Kernel</text></switch></g><rect x="0" y="610" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 635px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Root FS</div></div></div></foreignObject><text x="200" y="639" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Root FS</text></switch></g><rect x="0" y="660" width="400" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 690px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: rgb(0, 0, 0); "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Backup FWU Metadata<br />Partition Type GUID: 8a7a84a0-8387-40f6-ab41-a8b9a5a60d23</div></div></div></foreignObject><text x="200" y="694" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Backup FWU Metadata...</text></switch></g><rect x="0" y="720" width="400" height="60" fill="#f5f5f5" stroke="#666666" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 750px; margin-left: 1px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;" data-drawio-colors="color: #333333; "><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Backup GPT</div></div></div></foreignObject><text x="200" y="754" fill="#333333" font-family="Helvetica" font-size="12px" text-anchor="middle">Backup GPT</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="401px" height="781px" viewBox="-0.5 -0.5 401 781" content="&lt;mxfile host=&quot;app.diagrams.net&quot; agent=&quot;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0&quot; version=&quot;24.7.13&quot;&gt;&#10;  &lt;diagram id=&quot;MJao7NBNlqcqI8fyxszN&quot; name=&quot;Page-1&quot;&gt;&#10;    &lt;mxGraphModel dx=&quot;2466&quot; dy=&quot;1436&quot; grid=&quot;1&quot; gridSize=&quot;10&quot; guides=&quot;1&quot; tooltips=&quot;1&quot; connect=&quot;1&quot; arrows=&quot;1&quot; fold=&quot;1&quot; page=&quot;0&quot; pageScale=&quot;1&quot; pageWidth=&quot;850&quot; pageHeight=&quot;1100&quot; math=&quot;0&quot; shadow=&quot;0&quot;&gt;&#10;      &lt;root&gt;&#10;        &lt;mxCell id=&quot;0&quot; /&gt;&#10;        &lt;mxCell id=&quot;1&quot; parent=&quot;0&quot; /&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-1&quot; value=&quot;Protective MBR&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;-80&quot; width=&quot;400&quot; height=&quot;30&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-2&quot; value=&quot;Primary GPT&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;-50&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-3&quot; value=&quot;Primary FWU Metadata&amp;lt;br&amp;gt;Partition Type GUID:&amp;amp;nbsp;8a7a84a0-8387-40f6-ab41-a8b9a5a60d23&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;10&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-4&quot; value=&quot;0:AP-Firmware&amp;lt;br&amp;gt;Partition Type GUID:&amp;amp;nbsp;2451cd6e-90fe-4b15-bf10-a69bce2d4486&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;70&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-5&quot; value=&quot;1:AP-Firmware&amp;lt;br&amp;gt;Partition Type GUID:&amp;amp;nbsp;2451cd6e-90fe-4b15-bf10-a69bce2d4486&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;130&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-6&quot; value=&quot;0:SCP-Firmware&amp;lt;br&amp;gt;Partition Type GUID:&amp;amp;nbsp;691d5ea3-27fe-4104-badd-7539c00a9095&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;190&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-7&quot; value=&quot;1:SCP-Firmware&amp;lt;br&amp;gt;Partition Type GUID:&amp;amp;nbsp;691d5ea3-27fe-4104-badd-7539c00a9095&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;250&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-8&quot; value=&quot;0:RSE-Firmware&amp;lt;br&amp;gt;Partition Type GUID:&amp;amp;nbsp;c948a156-58cb-4c38-b406-e60bff2223d5&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;310&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-9&quot; value=&quot;1:RSE-Firmware&amp;lt;br&amp;gt;Partition Type GUID:&amp;amp;nbsp;c948a156-58cb-4c38-b406-e60bff2223d5&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;370&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-10&quot; value=&quot;UEFI-Variables&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;430&quot; width=&quot;400&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-11&quot; value=&quot;OS Kernel&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;480&quot; width=&quot;400&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-13&quot; value=&quot;Root FS&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;530&quot; width=&quot;400&quot; height=&quot;50&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-14&quot; value=&quot;Backup FWU Metadata&amp;lt;br&amp;gt;Partition Type GUID:&amp;amp;nbsp;8a7a84a0-8387-40f6-ab41-a8b9a5a60d23&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;580&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;        &lt;mxCell id=&quot;3oCrTGYNCdNRpomM2msj-15&quot; value=&quot;Backup GPT&quot; style=&quot;rounded=0;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;&quot; parent=&quot;1&quot; vertex=&quot;1&quot;&gt;&#10;          &lt;mxGeometry x=&quot;-80&quot; y=&quot;640&quot; width=&quot;400&quot; height=&quot;60&quot; as=&quot;geometry&quot; /&gt;&#10;        &lt;/mxCell&gt;&#10;      &lt;/root&gt;&#10;    &lt;/mxGraphModel&gt;&#10;  &lt;/diagram&gt;&#10;&lt;/mxfile&gt;&#10;"><defs/><g><g data-cell-id="0"><g data-cell-id="1"><g data-cell-id="3oCrTGYNCdNRpomM2msj-1"><g><rect x="0" y="0" width="400" height="30" fill="#f8cecc" stroke="#b85450" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 15px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Protective MBR</div></div></div></foreignObject><text x="200" y="19" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">Protective MBR</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-2"><g><rect x="0" y="30" width="400" height="60" fill="#f5f5f5" stroke="#666666" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 60px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Primary GPT</div></div></div></foreignObject><text x="200" y="64" fill="#333333" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">Primary GPT</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-3"><g><rect x="0" y="90" width="400" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 120px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Primary FWU Metadata<br />Partition Type GUID: 8a7a84a0-8387-40f6-ab41-a8b9a5a60d23</div></div></div></foreignObject><text x="200" y="124" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">Primary FWU Metadata...</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-4"><g><rect x="0" y="150" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 180px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:AP-Firmware<br />Partition Type GUID: 2451cd6e-90fe-4b15-bf10-a69bce2d4486</div></div></div></foreignObject><text x="200" y="184" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">0:AP-Firmware...</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-5"><g><rect x="0" y="210" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 240px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:AP-Firmware<br />Partition Type GUID: 2451cd6e-90fe-4b15-bf10-a69bce2d4486</div></div></div></foreignObject><text x="200" y="244" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">1:AP-Firmware...</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-6"><g><rect x="0" y="270" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 300px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:SCP-Firmware<br />Partition Type GUID: 691d5ea3-27fe-4104-badd-7539c00a9095</div></div></div></foreignObject><text x="200" y="304" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">0:SCP-Firmware...</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-7"><g><rect x="0" y="330" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 360px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:SCP-Firmware<br />Partition Type GUID: 691d5ea3-27fe-4104-badd-7539c00a9095</div></div></div></foreignObject><text x="200" y="364" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">1:SCP-Firmware...</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-8"><g><rect x="0" y="390" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 420px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">0:RSE-Firmware<br />Partition Type GUID: c948a156-58cb-4c38-b406-e60bff2223d5</div></div></div></foreignObject><text x="200" y="424" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">0:RSE-Firmware...</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-9"><g><rect x="0" y="450" width="400" height="60" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 480px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">1:RSE-Firmware<br />Partition Type GUID: c948a156-58cb-4c38-b406-e60bff2223d5</div></div></div></foreignObject><text x="200" y="484" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">1:RSE-Firmware...</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-10"><g><rect x="0" y="510" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 535px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">UEFI-Variables</div></div></div></foreignObject><text x="200" y="539" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">UEFI-Variables</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-11"><g><rect x="0" y="560" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 585px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">OS Kernel</div></div></div></foreignObject><text x="200" y="589" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">OS Kernel</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-13"><g><rect x="0" y="610" width="400" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 635px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Root FS</div></div></div></foreignObject><text x="200" y="639" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">Root FS</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-14"><g><rect x="0" y="660" width="400" height="60" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 690px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Backup FWU Metadata<br />Partition Type GUID: 8a7a84a0-8387-40f6-ab41-a8b9a5a60d23</div></div></div></foreignObject><text x="200" y="694" fill="rgb(0, 0, 0)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">Backup FWU Metadata...</text></switch></g></g></g><g data-cell-id="3oCrTGYNCdNRpomM2msj-15"><g><rect x="0" y="720" width="400" height="60" fill="#f5f5f5" stroke="#666666" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 398px; height: 1px; padding-top: 750px; margin-left: 1px;"><div data-drawio-colors="color: #333333; " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Backup GPT</div></div></div></foreignObject><text x="200" y="754" fill="#333333" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">Backup GPT</text></switch></g></g></g></g></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/docs/services/image/psa-fwu-m-block.svg b/docs/services/image/psa-fwu-m-block.svg
new file mode 100644
index 0000000..8d9b9d0
--- /dev/null
+++ b/docs/services/image/psa-fwu-m-block.svg
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Do not edit this file with editors other than draw.io -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="771px" height="261px" viewBox="-0.5 -0.5 771 261" content="&lt;mxfile host=&quot;Electron&quot; modified=&quot;2024-09-10T11:55:19.783Z&quot; agent=&quot;Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/21.6.8 Chrome/114.0.5735.289 Electron/25.5.0 Safari/537.36&quot; etag=&quot;9Li9al_JtGXNvUCZ0U1K&quot; version=&quot;21.6.8&quot; type=&quot;device&quot;&gt;&lt;diagram name=&quot;Page-1&quot; id=&quot;wsX4NXpH4iRoKw5mJQQR&quot;&gt;7Zhdc6IwFIZ/jTO7F3aACOglWt12pu10xt21vUwhQrqBOCF+9dfviQQBodadamtn9qZN3nzy5Lw5SAsN4tUPgWfRLQ8Ia1lGsGqhy5ZlWchE8E8p60wxkWllSihooLVCGNMXokVDq3MakLTSUXLOJJ1VRZ8nCfFlRcNC8GW125Sz6qozHJKaMPYxq6sTGsgoU7u2UehXhIZRvrJp6JYY5521kEY44MuShIYtNBCcy6wUrwaEKXo5l2zc6JXW7cYESeQhA+jE7j9b9O63d4XStXdzH73EbdPOpllgNtdPfNv2GU5TvWm5zkkIPk8CoiYzW6i/jKgk4xn2VesSDh+0SMZMNy+IkBQoeoyGCWiSqw56LWgjq1efwtyygagiPCZSrKGLHtDLceqA6uT1ZXE6Vn4GUelkLEeLWEdEuJ27gAYFze1fGHZqDL2zZojstxl2eh/LsIbwjosYq3ETLsCzZ0rS3SFp10matl0naZqnImnVSI6JPxcEtHsMGCTlyZnSdHa93UCz0duno4lqNH+O2rdnyq/XOSAanSZfn4xf/Wq8H3sgjCa/4K/Xv25ZDoNd9J8ElEJVur4C0TCMHqphJgHkZl3lQkY85Almw0LtFwdhQK3oc8MV5A3+ZyLlWr9o4Lnk1cMhKyofSuVHNdWFrWuXKz3zprLOKwmgeihXSqNUtRi2qeXjUgmG9NRLCgibhEH9XB5Rlm8pw6CefX9cACo+Fz7Zcxz6JoIFQiL39HOb40wQhiVdVPdx9Jipv5KUY2Ym+AJeCUU9cL79mgVYqovOC4HM9/e5dAoHMOCMi81YNJ0Sx89OR/A/pNQSuL0nwzjSDdixLuyqh7sHZpTTpWb3M31YeO+x1NLswyMaxT3QKKbzmU5x9zolJWJB4SmPaYPAJt2g02SDrvWEHOdIiczZSWRNJrAaEtnJTNBtIt1+I5NdDu8M0+z+T2PHTmNm/iXgLXvae8OsbVwYbkfPdbBj9XT3nMK2iy58Ok1hL7uBtl31HRdw/cdR2eY+owrg10t2qOsekuw+1OfZfV5hPaIiXmL1A2rX36nkQn0++voXrH1C8FAtPnJlnii+FaLhXw==&lt;/diagram&gt;&lt;/mxfile&gt;" style="background-color: rgb(255, 255, 255);"><defs/><g><rect x="570" y="0" width="200" height="260" rx="30" ry="30" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 198px; height: 1px; padding-top: 7px; margin-left: 571px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">M-class</div></div></div></foreignObject><text x="670" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">M-class</text></switch></g><rect x="0" y="0" width="490" height="260" rx="39" ry="39" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 488px; height: 1px; padding-top: 7px; margin-left: 1px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">A-class</div></div></div></foreignObject><text x="245" y="19" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">A-class</text></switch></g><rect x="20" y="30" width="155" height="110" rx="16.5" ry="16.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 153px; height: 1px; padding-top: 37px; margin-left: 21px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Normal World</div></div></div></foreignObject><text x="98" y="49" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Normal World</text></switch></g><rect x="270" y="30" width="200" height="110" rx="16.5" ry="16.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 198px; height: 1px; padding-top: 37px; margin-left: 271px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Secure Partition</div></div></div></foreignObject><text x="370" y="49" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Secure Partition</text></switch></g><rect x="590" y="30" width="160" height="210" rx="24" ry="24" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 37px; margin-left: 591px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">TF-M</div></div></div></foreignObject><text x="670" y="49" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">TF-M</text></switch></g><path d="M 453.87 90 L 603.63 90" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 448.62 90 L 455.62 86.5 L 453.87 90 L 455.62 93.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 608.88 90 L 601.88 93.5 L 603.63 90 L 601.88 86.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 90px; margin-left: 529px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">PSA FWU ABI<br />IHI 0093</div></div></div></foreignObject><text x="529" y="93" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">PSA FWU ABI...</text></switch></g><rect x="292.5" y="60" width="155" height="60" rx="9" ry="9" fill="#ffe6cc" stroke="#d79b00" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 153px; height: 1px; padding-top: 90px; margin-left: 293px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">PSA FWU provider<br />(Update Agent)</div></div></div></foreignObject><text x="370" y="94" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">PSA FWU provider...</text></switch></g><path d="M 670 120 L 670 153.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 670 158.88 L 666.5 151.88 L 670 153.63 L 673.5 151.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><rect x="610" y="60" width="120" height="60" rx="9" ry="9" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 90px; margin-left: 611px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">PSA FWU service</div></div></div></foreignObject><text x="670" y="94" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">PSA FWU service</text></switch></g><path d="M 163.87 90 L 286.13 90" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 158.62 90 L 165.62 86.5 L 163.87 90 L 165.62 93.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><path d="M 291.38 90 L 284.38 93.5 L 286.13 90 L 284.38 86.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 90px; margin-left: 220px;"><div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 11px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">PSA-A FWU ABI<br />DEN0118</div></div></div></foreignObject><text x="220" y="93" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="11px" text-anchor="middle">PSA-A FWU ABI...</text></switch></g><rect x="37.5" y="60" width="120" height="60" rx="9" ry="9" fill="#ffe6cc" stroke="#d79b00" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 90px; margin-left: 39px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">PSA FWU client</div></div></div></foreignObject><text x="98" y="94" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">PSA FWU client</text></switch></g><rect x="610" y="160" width="120" height="60" rx="9" ry="9" fill="#d5e8d4" stroke="#82b366" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 190px; margin-left: 611px;"><div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">Firmware<br />storage</div></div></div></foreignObject><text x="670" y="194" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">Firmware...</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Text is not SVG - cannot display</text></a></switch></svg>
\ No newline at end of file
diff --git a/docs/services/uml/psa_fwu_m_update_agent/fwu_accept.puml b/docs/services/uml/psa_fwu_m_update_agent/fwu_accept.puml
new file mode 100644
index 0000000..c497599
--- /dev/null
+++ b/docs/services/uml/psa_fwu_m_update_agent/fwu_accept.puml
@@ -0,0 +1,30 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+participant "PSA FWU A Update Client" as client
+participant "PSA FWU A Update Agent" as agent
+participant "PSA FWU M Service" as service
+
+autoactivate on
+
+client -> agent: fwu_accept_image()
+
+alt state == Trial
+	agent -> agent: mark image accepted
+	agent --> agent
+
+	alt all images accepted
+		agent -> service: psa_fwu_accept()
+		service --> agent
+		hnote over agent: state = Regular
+	end
+end
+
+agent --> client
+
+@enduml
diff --git a/docs/services/uml/psa_fwu_m_update_agent/fwu_begin_staging.puml b/docs/services/uml/psa_fwu_m_update_agent/fwu_begin_staging.puml
new file mode 100644
index 0000000..5bec1ab
--- /dev/null
+++ b/docs/services/uml/psa_fwu_m_update_agent/fwu_begin_staging.puml
@@ -0,0 +1,36 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+participant "PSA FWU A Update Client" as client
+participant "PSA FWU A Update Agent" as agent
+participant "PSA FWU M Service" as service
+
+autoactivate on
+
+client -> agent: fwu_begin_staging()
+
+alt state == Staging
+	agent -> agent: fwu_cancel_staging()
+	agent --> agent
+
+	loop on all images
+		agent -> service: psa_fwu_clean(image)
+		service --> agent
+	end
+end
+
+loop on selected images
+	agent -> service: psa_fwu_start(image)
+	service --> agent
+end
+
+hnote over agent: state = Staging
+
+agent --> client
+
+@enduml
diff --git a/docs/services/uml/psa_fwu_m_update_agent/fwu_cancel_staging.puml b/docs/services/uml/psa_fwu_m_update_agent/fwu_cancel_staging.puml
new file mode 100644
index 0000000..48cf3f8
--- /dev/null
+++ b/docs/services/uml/psa_fwu_m_update_agent/fwu_cancel_staging.puml
@@ -0,0 +1,28 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+participant "PSA FWU A Update Client" as client
+participant "PSA FWU A Update Agent" as agent
+participant "PSA FWU M Service" as service
+
+autoactivate on
+
+client -> agent: fwu_cancel_staging()
+
+alt state == Staging
+	loop on all selected images
+		agent -> service: psa_fwu_cancel(image)
+		service --> agent
+	end
+
+	hnote over agent: state = Regular
+end
+
+agent --> client
+
+@enduml
diff --git a/docs/services/uml/psa_fwu_m_update_agent/fwu_end_staging.puml b/docs/services/uml/psa_fwu_m_update_agent/fwu_end_staging.puml
new file mode 100644
index 0000000..631ddf1
--- /dev/null
+++ b/docs/services/uml/psa_fwu_m_update_agent/fwu_end_staging.puml
@@ -0,0 +1,37 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+participant "PSA FWU A Update Client" as client
+participant "PSA FWU A Update Agent" as agent
+participant "PSA FWU M Service" as service
+
+autoactivate on
+
+client -> agent: fwu_end_staging()
+
+alt state == Staging
+	loop on all selected images
+		agent -> service: psa_fwu_finish(image)
+		service --> agent
+	end
+
+	agent -> service: psa_fwu_install()
+	service --> agent
+
+	alt all images accepted
+		agent -> service: psa_fwu_accept()
+		service --> agent
+		hnote over agent: state = Regular
+	else
+		hnote over agent: state = Trial
+	end
+end
+
+agent --> client
+
+@enduml
diff --git a/docs/services/uml/psa_fwu_m_update_agent/fwu_select_previous.puml b/docs/services/uml/psa_fwu_m_update_agent/fwu_select_previous.puml
new file mode 100644
index 0000000..985e496
--- /dev/null
+++ b/docs/services/uml/psa_fwu_m_update_agent/fwu_select_previous.puml
@@ -0,0 +1,25 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+participant "PSA FWU A Update Client" as client
+participant "PSA FWU A Update Agent" as agent
+participant "PSA FWU M Service" as service
+
+autoactivate on
+
+client -> agent: fwu_select_previous()
+
+alt state == Trial
+	agent -> service: psa_fwu_reject(0)
+	service --> agent
+	hnote over agent: state = Regular
+end
+
+agent --> client
+
+@enduml
diff --git a/docs/services/uml/psa_fwu_m_update_agent/image_directory.puml b/docs/services/uml/psa_fwu_m_update_agent/image_directory.puml
new file mode 100644
index 0000000..51434a9
--- /dev/null
+++ b/docs/services/uml/psa_fwu_m_update_agent/image_directory.puml
@@ -0,0 +1,30 @@
+'-------------------------------------------------------------------------------
+' Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+'
+' SPDX-License-Identifier: BSD-3-Clause
+'
+'-------------------------------------------------------------------------------
+
+@startuml
+participant "PSA FWU A Update Client" as client
+participant "PSA FWU A Update Agent" as agent
+participant "PSA FWU M Service" as service
+
+autoactivate on
+
+client -> agent: fwu_read_stream(image directory)
+
+agent -> agent: fill image_directory structure
+agent --> agent
+
+loop on all images
+	agent -> service: psa_fwu_query(image)
+	service --> agent: psa_fwu_component_info_t
+
+	agent -> agent: convert psa_fwu_component_info_t to img_info_entry
+	agent --> agent: img_info_entry
+end
+
+agent --> client
+
+@enduml
diff --git a/docs/target-platforms/Corstone1000.rst b/docs/target-platforms/Corstone1000.rst
new file mode 100644
index 0000000..8a89b7c
--- /dev/null
+++ b/docs/target-platforms/Corstone1000.rst
@@ -0,0 +1,20 @@
+Corstone-1000
+=============
+
+Corstone-1000 is an Arm reference platform which is built upon a pre-verified Corstone SSE-710 subsystem that provides a
+flexible compute architecture which combines Cortex®â€‘A and Cortex®â€‘M processors.
+
+For more information please see the following resources:
+
+    - `Corstone-1000 product homepage`_.
+    - Documentation of the `Corstone-1000 software stack`_.
+
+--------------
+
+.. _`Corstone-1000 product homepage`: https://developer.arm.com/Processors/Corstone-1000
+.. _`Corstone-1000 software stack`: https://corstone1000.docs.arm.com/en/latest/
+
+*Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.*
+
+SPDX-License-Identifier: BSD-3-Clause
+
diff --git a/docs/target-platforms/aem-fvp.rst b/docs/target-platforms/aem-fvp.rst
index a2d4ad6..d49c4dc 100644
--- a/docs/target-platforms/aem-fvp.rst
+++ b/docs/target-platforms/aem-fvp.rst
@@ -12,7 +12,7 @@
 --------------
 
 .. _`Fixed Virtual Platforms`: https://developer.arm.com/Tools%20and%20Software/Fixed%20Virtual%20Platforms
-.. _`Armv-A Base RevC AEM FVP`: https://developer.arm.com/-/media/Files/downloads/ecosystem-models/FVP_Base_RevC-2xAEMvA_11.18_16_Linux64.tgz
+.. _`Armv-A Base RevC AEM FVP`: https://developer.arm.com/-/media/Files/downloads/ecosystem-models/FVP_Base_RevC-2xAEMvA_11.22_14_Linux64.tgz
 
 *Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.*
 
diff --git a/docs/target-platforms/index.rst b/docs/target-platforms/index.rst
index 49bffb1..a271889 100644
--- a/docs/target-platforms/index.rst
+++ b/docs/target-platforms/index.rst
@@ -16,13 +16,12 @@
    - Obsolete
      Platforms which are not tested for the current release are put into this category.
 
-   - Deprecated Platforms not tested for more than one two are threated as obsolete, and will be
-     removed for the next release.
+   - Deprecated Platforms not tested for more than one two releases are threated as obsolete, and
+     will be removed for the next release.
 
 The quality of the platform, known issues, feature limitations, extra features, etc... are defined
 in the sub-chapters below.
 
-
 Reference platforms
 -------------------
 
@@ -31,6 +30,16 @@
 
     ./aem-fvp
 
+Active Platforms
+----------------
+
+These platforms are not maintained by the Trusted Services project and are contributed externally. Instructions about
+building and running the software stacks of these platforms is out of scope for TS documentation.
+
+.. toctree::
+    :maxdepth: 1
+
+    ./Corstone1000
 
 --------------
 
diff --git a/environments/arm-linux/component.cmake b/environments/arm-linux/component.cmake
new file mode 100644
index 0000000..97229bd
--- /dev/null
+++ b/environments/arm-linux/component.cmake
@@ -0,0 +1,25 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+if (NOT DEFINED TRACE_PREFIX)
+	message(FATAL_ERROR "mandatory parameter TRACE_PREFIX is not defined.")
+endif()
+
+# Default to trace output disabled
+set(TRACE_LEVEL "TRACE_LEVEL_NONE" CACHE STRING "Trace level")
+
+target_compile_definitions(${TGT} PRIVATE
+	TRACE_LEVEL=${TRACE_LEVEL}
+	TRACE_PREFIX="${TRACE_PREFIX}"
+)
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/posix_trace.c"
+	)
diff --git a/environments/arm-linux/default_toolchain_file.cmake b/environments/arm-linux/default_toolchain_file.cmake
index 1da144e..7e565dd 100644
--- a/environments/arm-linux/default_toolchain_file.cmake
+++ b/environments/arm-linux/default_toolchain_file.cmake
@@ -22,20 +22,40 @@
 set(TS_WARNING_FLAGS "-Wall -Werror" CACHE STRING "Compiler flags affecting generating warning messages.")
 set(TS_MANDATORY_LINKER_FLAGS "" CACHE STRING "Linker flags needed for correct builds.")
 
+# branch-protection enables bti/pac while compile force-bti tells the linker to
+# warn if some object files lack the .note.gnu.property section with the BTI
+# flag, and to turn on the BTI flag in the output anyway.
+set(BRANCH_PROTECTION unset CACHE STRING "Enable branch protection")
+set_property(CACHE BRANCH_PROTECTION PROPERTY STRINGS unset 0 1 2 3 4)
+
+if(BRANCH_PROTECTION STREQUAL "0")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=none")
+elseif(BRANCH_PROTECTION STREQUAL "1")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=standard")
+	set(TS_MANDATORY_LINKER_FLAGS "${TS_MANDATORY_LINKER_FLAGS} -zforce-bti")
+	add_compile_definitions("BTI_ENABLED")
+elseif(BRANCH_PROTECTION STREQUAL "2")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=pac-ret")
+elseif(BRANCH_PROTECTION STREQUAL "3")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=pac-ret+leaf")
+elseif(BRANCH_PROTECTION STREQUAL "4")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=bti")
+	set(TS_MANDATORY_LINKER_FLAGS "${TS_MANDATORY_LINKER_FLAGS} -zforce-bti")
+	add_compile_definitions("BTI_ENABLED")
+endif()
+
 # Set flags affecting all build types
-foreach(_b_type IN ITEMS DEBUG MINSIZEREL MINSIZWITHDEBINFO RELEASE RELWITHDEBINFO)
-	string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
-	string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
-	string(APPEND CMAKE_EXE_LINKER_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
-	if(DEFINED TS_ROOT)
-		# Flags not to be used with external components.
-		string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
-		string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
-	endif()
-endforeach()
+string(APPEND CMAKE_C_FLAGS_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+string(APPEND CMAKE_CXX_FLAGS_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
+if(DEFINED TS_ROOT)
+	# Flags not to be used with external components.
+	string(APPEND CMAKE_C_FLAGS_INIT " ${TS_WARNING_FLAGS}")
+	string(APPEND CMAKE_CXX_FLAGS_INIT " ${TS_WARNING_FLAGS}")
+endif()
 
 # Set flags affecting all build types supporting debugging.
-foreach(_b_type IN ITEMS DEBUG RELWITHDEBINFO MINSIZWITHDEBINFO)
+foreach(_b_type IN ITEMS DEBUG RELWITHDEBINFO MINSIZWITHDEBINFO DEBUGCOVERAGE)
 	string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_DEBUG_INFO_FLAGS}")
 	string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_DEBUG_INFO_FLAGS}")
 endforeach()
@@ -46,11 +66,13 @@
 string(APPEND CMAKE_C_FLAGS_MINSIZWITHDEBINFO_INIT " -Os")
 string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -O2")
 string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -O2")
+string(APPEND CMAKE_C_FLAGS_DEBUGCOVERAGE_INIT " -O0 -coverage")
 string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " -O0")
 string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT  " -Os")
 string(APPEND CMAKE_CXX_FLAGS_MINSIZWITHDEBINFO_INIT " -Os")
 string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -O2")
 string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -O2")
+string(APPEND CMAKE_CXX_FLAGS_DEBUGCOVERAGE_INIT " -O0 -coverage")
 
 include($ENV{TS_ROOT}/tools/cmake/compiler/GCC.cmake REQUIRED)
 include($ENV{TS_ROOT}/tools/cmake/compiler/config_iface.cmake REQUIRED)
diff --git a/environments/arm-linux/posix_trace.c b/environments/arm-linux/posix_trace.c
new file mode 100644
index 0000000..f219b6d
--- /dev/null
+++ b/environments/arm-linux/posix_trace.c
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ */
+
+#include <stdio.h>
+
+#include "trace.h"
+
+#if TRACE_LEVEL >= TRACE_LEVEL_ERROR
+
+void trace_puts(const char *str)
+{
+	puts(str);
+}
+
+#endif /* TRACE_LEVEL >= TRACE_LEVEL_ERROR */
diff --git a/environments/linux-pc/default_toolchain_file.cmake b/environments/linux-pc/default_toolchain_file.cmake
index 58f29bc..2215d6b 100644
--- a/environments/linux-pc/default_toolchain_file.cmake
+++ b/environments/linux-pc/default_toolchain_file.cmake
@@ -15,19 +15,17 @@
 set(TS_MANDATORY_LINKER_FLAGS "" CACHE STRING "Linker flags needed for correct builds.")
 
 # Set flags affecting all build types
-foreach(_b_type IN ITEMS DEBUG MINSIZEREL MINSIZWITHDEBINFO RELEASE RELWITHDEBINFO)
-	string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
-	string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
-	string(APPEND CMAKE_EXE_LINKER_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
-	if(DEFINED TS_ROOT)
-		# Flags not to be used with external components.
-		string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
-		string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
-	endif()
-endforeach()
+string(APPEND CMAKE_C_FLAGS_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+string(APPEND CMAKE_CXX_FLAGS_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
+if(DEFINED TS_ROOT)
+	# Flags not to be used with external components.
+	string(APPEND CMAKE_C_FLAGS_INIT " ${TS_WARNING_FLAGS}")
+	string(APPEND CMAKE_CXX_FLAGS_INIT " ${TS_WARNING_FLAGS}")
+endif()
 
 # Set flags affecting all build types supporting debugging.
-foreach(_b_type IN ITEMS DEBUG RELWITHDEBINFO MINSIZWITHDEBINFO)
+foreach(_b_type IN ITEMS DEBUG RELWITHDEBINFO MINSIZWITHDEBINFO DEBUGCOVERAGE)
 	string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_DEBUG_INFO_FLAGS}")
 	string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_DEBUG_INFO_FLAGS}")
 endforeach()
@@ -38,11 +36,13 @@
 string(APPEND CMAKE_C_FLAGS_MINSIZWITHDEBINFO_INIT " -Os")
 string(APPEND CMAKE_C_FLAGS_RELEASE_INIT " -O2")
 string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO_INIT " -O2")
+string(APPEND CMAKE_C_FLAGS_DEBUGCOVERAGE_INIT " -O0 -coverage")
 string(APPEND CMAKE_CXX_FLAGS_DEBUG_INIT " -O0")
 string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL_INIT  " -Os")
 string(APPEND CMAKE_CXX_FLAGS_MINSIZWITHDEBINFO_INIT " -Os")
 string(APPEND CMAKE_CXX_FLAGS_RELEASE_INIT " -O2")
 string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT " -O2")
+string(APPEND CMAKE_CXX_FLAGS_DEBUGCOVERAGE_INIT " -O0 -coverage")
 
 include($ENV{TS_ROOT}/tools/cmake/compiler/GCC.cmake REQUIRED)
 include($ENV{TS_ROOT}/tools/cmake/compiler/config_iface.cmake REQUIRED)
diff --git a/environments/opteesp/component.cmake b/environments/opteesp/component.cmake
index 2b54682..3726e2f 100644
--- a/environments/opteesp/component.cmake
+++ b/environments/opteesp/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -63,7 +63,12 @@
 	SP_HEAP_SIZE=${SP_HEAP_SIZE}
 )
 
-include(${TS_ROOT}/external/newlib/newlib.cmake)
+add_subdirectory(${TS_ROOT}/components/common/libc ${CMAKE_BINARY_DIR}/libc_build)
+add_components(TARGET ${TGT}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/common/dlmalloc"
+)
 
 target_link_libraries(${TGT} PRIVATE
  	stdlib::c
diff --git a/environments/opteesp/default_toolchain_file.cmake b/environments/opteesp/default_toolchain_file.cmake
index 43c19c5..b150b85 100644
--- a/environments/opteesp/default_toolchain_file.cmake
+++ b/environments/opteesp/default_toolchain_file.cmake
@@ -25,17 +25,37 @@
 set(TS_MANDATORY_LINKER_FLAGS "-pie -Wl,--as-needed -Wl,--sort-section=alignment -zmax-page-size=4096"
 	CACHE STRING "Linker flags needed for correct builds.")
 
+# branch-protection enables bti/pac while compile force-bti tells the linker to
+# warn if some object files lack the .note.gnu.property section with the BTI
+# flag, and to turn on the BTI flag in the output anyway.
+set(BRANCH_PROTECTION unset CACHE STRING "Enable branch protection")
+set_property(CACHE BRANCH_PROTECTION PROPERTY STRINGS unset 0 1 2 3 4)
+
+if(BRANCH_PROTECTION STREQUAL "0")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=none")
+elseif(BRANCH_PROTECTION STREQUAL "1")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=standard")
+	set(TS_MANDATORY_LINKER_FLAGS "${TS_MANDATORY_LINKER_FLAGS} -zforce-bti")
+	add_compile_definitions("BTI_ENABLED")
+elseif(BRANCH_PROTECTION STREQUAL "2")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=pac-ret")
+elseif(BRANCH_PROTECTION STREQUAL "3")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=pac-ret+leaf")
+elseif(BRANCH_PROTECTION STREQUAL "4")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=bti")
+	set(TS_MANDATORY_LINKER_FLAGS "${TS_MANDATORY_LINKER_FLAGS} -zforce-bti")
+	add_compile_definitions("BTI_ENABLED")
+endif()
+
 # Set flags affecting all build types
-foreach(_b_type IN ITEMS DEBUG MINSIZEREL MINSIZWITHDEBINFO RELEASE RELWITHDEBINFO)
-	string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
-	string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
-	string(APPEND CMAKE_EXE_LINKER_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
-	if(DEFINED TS_ROOT)
-		# Flags not to be used with external components.
-		string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
-		string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
-	endif()
-endforeach()
+string(APPEND CMAKE_C_FLAGS_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+string(APPEND CMAKE_CXX_FLAGS_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
+if(DEFINED TS_ROOT)
+	# Flags not to be used with external components.
+	string(APPEND CMAKE_C_FLAGS_INIT " ${TS_WARNING_FLAGS}")
+	string(APPEND CMAKE_CXX_FLAGS_INIT " ${TS_WARNING_FLAGS}")
+endif()
 
 # Set flags affecting all build types supporting debugging.
 foreach(_b_type IN ITEMS DEBUG RELWITHDEBINFO MINSIZWITHDEBINFO)
diff --git a/environments/opteesp/sp.ld.S b/environments/opteesp/sp.ld.S
index a3999f2..e5d3545 100644
--- a/environments/opteesp/sp.ld.S
+++ b/environments/opteesp/sp.ld.S
@@ -52,6 +52,7 @@
 	.dynstr : { *(.dynstr) }
 	.hash : { *(.hash) }
 	.note.gnu.build-id : { *(.note.gnu.build-id) }
+	.note.gnu.property : { *(.note.gnu.property) }
 
 	/* Page align to allow dropping execute bit for RW data */
 	. = ALIGN(4096);
diff --git a/environments/opteesp/sp_assert.c b/environments/opteesp/sp_assert.c
index 8f336e7..8690c8a 100644
--- a/environments/opteesp/sp_assert.c
+++ b/environments/opteesp/sp_assert.c
@@ -1,20 +1,29 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  */
 
-#include "assert_fail_handler.h"
-#include "compiler.h"
+#include "libc_platform.h"
 #include "trace.h"
 
 /*
  * The generic trace function called on assert fail.
  */
-void __noreturn assert_fail_handler(const char *file, int line,
-				    const char *func, const char *failedexpr)
+void __noreturn platform_assert(const char *file, int line, const char *func,
+				const char *failedexpr)
 {
 #if TRACE_LEVEL >= TRACE_LEVEL_ERROR
-	trace_printf(func, line, TRACE_LEVEL_ERROR, "assertion %s failed", failedexpr);
+	ts_trace_printf(func, line, TRACE_LEVEL_ERROR, "assertion %s failed", failedexpr);
+#endif /* TRACE_LEVEL */
+
+	while (1)
+		;
+}
+
+void __noreturn platform_abort(void)
+{
+#if TRACE_LEVEL >= TRACE_LEVEL_ERROR
+	trace_puts("abort()");
 #endif /* TRACE_LEVEL */
 
 	while (1)
diff --git a/environments/opteesp/sp_entry.c b/environments/opteesp/sp_entry.c
index f7d67cb..1580840 100644
--- a/environments/opteesp/sp_entry.c
+++ b/environments/opteesp/sp_entry.c
@@ -1,12 +1,11 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  */
 
 #include <stddef.h>
 #include <stdint.h>
 #include "compiler.h"
-#include "libc_init.h"
 #include "sp_api.h"
 
 /*
@@ -24,7 +23,5 @@
 	(void)a2;
 	(void)a3;
 
-	libc_init();
-
 	sp_main((union ffa_boot_info *)a0);
 }
diff --git a/environments/sp/component.cmake b/environments/sp/component.cmake
index 35532bd..5644ed1 100644
--- a/environments/sp/component.cmake
+++ b/environments/sp/component.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -36,7 +36,12 @@
 	SP_HEAP_SIZE=${SP_HEAP_SIZE}
 )
 
-include(${TS_ROOT}/external/newlib/newlib.cmake)
+add_subdirectory(${TS_ROOT}/components/common/libc ${CMAKE_BINARY_DIR}/libc_build)
+add_components(TARGET ${TGT}
+	BASE_DIR ${TS_ROOT}
+	COMPONENTS
+		"components/common/dlmalloc"
+)
 
 target_link_libraries(${TGT} PRIVATE
 	stdlib::c
diff --git a/environments/sp/default_toolchain_file.cmake b/environments/sp/default_toolchain_file.cmake
index 31febe5..d41ecec 100644
--- a/environments/sp/default_toolchain_file.cmake
+++ b/environments/sp/default_toolchain_file.cmake
@@ -24,17 +24,37 @@
 set(TS_WARNING_FLAGS "-Wall" CACHE STRING "Compiler flags affecting generating warning messages.")
 set(TS_MANDATORY_LINKER_FLAGS "-Wl,-pie -Wl,--no-dynamic-linker -Wl,--sort-section=alignment -zmax-page-size=4096" CACHE STRING "Linker flags needed for correct builds.")
 
+# branch-protection enables bti/pac while compile force-bti tells the linker to
+# warn if some object files lack the .note.gnu.property section with the BTI
+# flag, and to turn on the BTI flag in the output anyway.
+set(BRANCH_PROTECTION unset CACHE STRING "Enable branch protection")
+set_property(CACHE BRANCH_PROTECTION PROPERTY STRINGS unset 0 1 2 3 4)
+
+if(BRANCH_PROTECTION STREQUAL "0")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=none")
+elseif(BRANCH_PROTECTION STREQUAL "1")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=standard")
+	set(TS_MANDATORY_LINKER_FLAGS "${TS_MANDATORY_LINKER_FLAGS} -zforce-bti")
+	add_compile_definitions("BTI_ENABLED")
+elseif(BRANCH_PROTECTION STREQUAL "2")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=pac-ret")
+elseif(BRANCH_PROTECTION STREQUAL "3")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=pac-ret+leaf")
+elseif(BRANCH_PROTECTION STREQUAL "4")
+	set(TS_MANDATORY_AARCH_FLAGS "${TS_MANDATORY_AARCH_FLAGS} -mbranch-protection=bti")
+	set(TS_MANDATORY_LINKER_FLAGS "${TS_MANDATORY_LINKER_FLAGS} -zforce-bti")
+	add_compile_definitions("BTI_ENABLED")
+endif()
+
 # Set flags affecting all build types
-foreach(_b_type IN ITEMS DEBUG MINSIZEREL MINSIZWITHDEBINFO RELEASE RELWITHDEBINFO)
-	string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
-	string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
-	string(APPEND CMAKE_EXE_LINKER_FLAGS_${_b_type}_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
-	if(DEFINED TS_ROOT)
-		# Flags not to be used with external components.
-		string(APPEND CMAKE_C_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
-		string(APPEND CMAKE_CXX_FLAGS_${_b_type}_INIT " ${TS_WARNING_FLAGS}")
-	endif()
-endforeach()
+string(APPEND CMAKE_C_FLAGS_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+string(APPEND CMAKE_CXX_FLAGS_INIT " ${TS_MANDATORY_AARCH_FLAGS}")
+string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${TS_MANDATORY_LINKER_FLAGS}")
+if(DEFINED TS_ROOT)
+	# Flags not to be used with external components.
+	string(APPEND CMAKE_C_FLAGS_INIT " ${TS_WARNING_FLAGS}")
+	string(APPEND CMAKE_CXX_FLAGS_INIT " ${TS_WARNING_FLAGS}")
+endif()
 
 # Set flags affecting all build types supporting debugging.
 foreach(_b_type IN ITEMS DEBUG RELWITHDEBINFO MINSIZWITHDEBINFO)
diff --git a/environments/sp/entry.S b/environments/sp/entry.S
index 29c61c3..ab6c0af 100644
--- a/environments/sp/entry.S
+++ b/environments/sp/entry.S
@@ -83,3 +83,5 @@
 	.asciz "Only R_AARCH64_RELATIVE type relocation is supported"
 	.align 8
 END_FUNC __sp_entry
+
+BTI(emit_aarch64_feature_1_and     GNU_PROPERTY_AARCH64_FEATURE_1_BTI)
diff --git a/environments/sp/sp.ld.S b/environments/sp/sp.ld.S
index 7a57a97..3e0e69e 100644
--- a/environments/sp/sp.ld.S
+++ b/environments/sp/sp.ld.S
@@ -51,6 +51,7 @@
 	.dynstr : { *(.dynstr) }
 	.hash : { *(.hash) }
 	.note.gnu.build-id : { *(.note.gnu.build-id) }
+	.note.gnu.property : { *(.note.gnu.property) }
 
 	. = ALIGN(8);
 	__rela_start = .;
@@ -97,10 +98,10 @@
 		__bss_end = .;
 	}
 	.stack : {
-		. = ALIGN(4);
+		. = ALIGN(16);
 		__stack_start = .;
 		. += SP_STACK_SIZE;
-		. = ALIGN(4);
+		. = ALIGN(16);
 		__stack_end = .;
 	}
 
diff --git a/environments/sp/sp_assert.c b/environments/sp/sp_assert.c
index 8f336e7..8690c8a 100644
--- a/environments/sp/sp_assert.c
+++ b/environments/sp/sp_assert.c
@@ -1,20 +1,29 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  */
 
-#include "assert_fail_handler.h"
-#include "compiler.h"
+#include "libc_platform.h"
 #include "trace.h"
 
 /*
  * The generic trace function called on assert fail.
  */
-void __noreturn assert_fail_handler(const char *file, int line,
-				    const char *func, const char *failedexpr)
+void __noreturn platform_assert(const char *file, int line, const char *func,
+				const char *failedexpr)
 {
 #if TRACE_LEVEL >= TRACE_LEVEL_ERROR
-	trace_printf(func, line, TRACE_LEVEL_ERROR, "assertion %s failed", failedexpr);
+	ts_trace_printf(func, line, TRACE_LEVEL_ERROR, "assertion %s failed", failedexpr);
+#endif /* TRACE_LEVEL */
+
+	while (1)
+		;
+}
+
+void __noreturn platform_abort(void)
+{
+#if TRACE_LEVEL >= TRACE_LEVEL_ERROR
+	trace_puts("abort()");
 #endif /* TRACE_LEVEL */
 
 	while (1)
diff --git a/environments/sp/sp_entry.c b/environments/sp/sp_entry.c
index c9b2510..f683646 100644
--- a/environments/sp/sp_entry.c
+++ b/environments/sp/sp_entry.c
@@ -1,12 +1,11 @@
 // SPDX-License-Identifier: BSD-3-Clause
 /*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
  */
 
 #include <stddef.h>
 #include <stdint.h>
 #include "compiler.h"
-#include "libc_init.h"
 #include "sp_api.h"
 
 /*
@@ -24,7 +23,5 @@
 	(void)a2;
 	(void)a3;
 
-	libc_init();
-
 	sp_main((union ffa_boot_info *)a0);
 }
diff --git a/external/CppUTest/cpputest-init-cache.cmake.in b/external/CppUTest/cpputest-init-cache.cmake.in
index b24f5de..c3801cc 100644
--- a/external/CppUTest/cpputest-init-cache.cmake.in
+++ b/external/CppUTest/cpputest-init-cache.cmake.in
@@ -10,6 +10,7 @@
 set(MEMORY_LEAK_DETECTION OFF CACHE BOOL "")
 set(LONGLONG ON CACHE BOOL "")
 set(C++11 ON CACHE BOOL "")
+set(BRANCH_PROTECTION @BRANCH_PROTECTION@ CACHE STRING "")
 
 string(TOUPPER @CMAKE_CROSSCOMPILING@ CMAKE_CROSSCOMPILING) # CMake expects TRUE
 if (CMAKE_CROSSCOMPILING)
diff --git a/external/LinuxFfaTeeDriver/LinuxFfaTeeDriver.cmake b/external/LinuxFfaTeeDriver/LinuxFfaTeeDriver.cmake
deleted file mode 100644
index da0a5b3..0000000
--- a/external/LinuxFfaTeeDriver/LinuxFfaTeeDriver.cmake
+++ /dev/null
@@ -1,54 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-
-# If the driver is already installed, try to find that
-find_path(LINUX_FFA_TEE_DRIVER_INCLUDE_DIR
-	NAMES arm_tstee.h
-	DOC "Linux FF-A TEE driver include directory"
-)
-
-# If not found, download it
-if(NOT LINUX_FFA_TEE_DRIVER_INCLUDE_DIR)
-	set(LINUX_FFA_TEE_DRIVER_URL "https://git.gitlab.arm.com/linux-arm/linux-trusted-services.git"
-		CACHE STRING "Linux FF-A TEE driver repository URL")
-
-	# Note: the aim of this external component is to make the header file defining the IOCTL API
-	#        available. Fetching a moving reference is ok as long as API compatibility is guaranteed.
-	set(LINUX_FFA_TEE_DRIVER_REFSPEC "origin/tee-v2"
-		CACHE STRING "Linux FF-A TEE driver git refspec")
-
-	set(LINUX_FFA_TEE_DRIVER_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/linux_ffa_tee_driver-src"
-		CACHE PATH "Location of Linux TEE driver source.")
-
-	if (DEFINED ENV{LINUX_FFA_TEE_DRIVER_SOURCE_DIR})
-		set(LINUX_FFA_TEE_DRIVER_SOURCE_DIR $ENV{LINUX_FFA_TEE_DRIVER_SOURCE_DIR}
-			CACHE PATH "Location of Linux TEE driver source." FORCE)
-	endif()
-
-	set(GIT_OPTIONS
-		GIT_REPOSITORY ${LINUX_FFA_TEE_DRIVER_URL}
-		GIT_TAG ${LINUX_FFA_TEE_DRIVER_REFSPEC}
-		GIT_SHALLOW TRUE
-		)
-		include(${TS_ROOT}/tools/cmake/common/LazyFetch.cmake REQUIRED)
-		LazyFetch_MakeAvailable(
-			DEP_NAME linux_ffa_tee_driver
-			FETCH_OPTIONS "${GIT_OPTIONS}"
-			SOURCE_DIR ${LINUX_FFA_TEE_DRIVER_SOURCE_DIR}
-		)
-
-	find_path(LINUX_FFA_TEE_DRIVER_INCLUDE_DIR
-		NAMES arm_tstee.h
-		PATHS ${LINUX_FFA_TEE_DRIVER_SOURCE_DIR}/uapi
-		NO_DEFAULT_PATH
-		REQUIRED
-		DOC "Linux FF-A TEE driver include directory"
-	)
-endif()
-
-set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
-	"${LINUX_FFA_TEE_DRIVER_INCLUDE_DIR}/arm_tstee.h")
diff --git a/external/MbedTLS/0001-Add-capability-to-selectively-build-libraries.patch b/external/MbedTLS/0001-Add-capability-to-selectively-build-libraries.patch
index 2f31613..32ba59f 100644
--- a/external/MbedTLS/0001-Add-capability-to-selectively-build-libraries.patch
+++ b/external/MbedTLS/0001-Add-capability-to-selectively-build-libraries.patch
@@ -1,7 +1,7 @@
-From ee65a0f8164db4531d35aa40db7b2f066cd333d7 Mon Sep 17 00:00:00 2001
+From 009b346144f4efd6c7f6ca0ceaead89e7333bba7 Mon Sep 17 00:00:00 2001
 From: Gyorgy Szing <Gyorgy.Szing@arm.com>
 Date: Tue, 28 Mar 2023 18:20:44 +0200
-Subject: [PATCH 1/1] Add capability to selectively build libraries
+Subject: [PATCH] Add capability to selectively build libraries
 
 Introduce the BUILD_X509 and BUILD_TLS options which allows disabling
 or enabling building of these libraries.
@@ -17,7 +17,7 @@
  1 file changed, 57 insertions(+), 20 deletions(-)
 
 diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt
-index eeda06aee..d79c657fd 100644
+index e6705de55..3244bd086 100644
 --- a/library/CMakeLists.txt
 +++ b/library/CMakeLists.txt
 @@ -2,6 +2,8 @@ option(USE_STATIC_MBEDTLS_LIBRARY "Build Mbed TLS static library." ON)
@@ -29,7 +29,7 @@
  
  # Set the project root directory if it's not already defined, as may happen if
  # the library folder is included directly by a parent project, without
-@@ -255,7 +257,15 @@ if (USE_STATIC_MBEDTLS_LIBRARY)
+@@ -257,7 +259,15 @@ if (USE_STATIC_MBEDTLS_LIBRARY)
      set(mbedcrypto_static_target ${mbedcrypto_target})
  endif()
  
@@ -46,7 +46,7 @@
  
  if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
      string(APPEND mbedtls_static_target    "_static")
-@@ -263,9 +273,15 @@ if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
+@@ -265,9 +275,15 @@ if(USE_STATIC_MBEDTLS_LIBRARY AND USE_SHARED_MBEDTLS_LIBRARY)
      string(APPEND mbedcrypto_static_target "_static")
  
      list(APPEND target_libraries
@@ -65,7 +65,7 @@
  endif()
  
  set(p256m_target "${MBEDTLS_TARGET_PREFIX}p256m")
-@@ -284,13 +300,17 @@ if(USE_STATIC_MBEDTLS_LIBRARY)
+@@ -286,13 +302,17 @@ if(USE_STATIC_MBEDTLS_LIBRARY)
          target_link_libraries(${mbedcrypto_static_target} PUBLIC ${p256m_target})
      endif()
  
@@ -89,32 +89,32 @@
  endif(USE_STATIC_MBEDTLS_LIBRARY)
  
  if(USE_SHARED_MBEDTLS_LIBRARY)
-@@ -306,14 +326,16 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
+@@ -308,14 +328,16 @@ if(USE_SHARED_MBEDTLS_LIBRARY)
      if(TARGET ${p256m_target})
          target_link_libraries(${mbedcrypto_target} PUBLIC ${p256m_target})
      endif()
 -
 -    add_library(${mbedx509_target} SHARED ${src_x509})
--    set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.5.1 SOVERSION 6)
+-    set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.0 SOVERSION 7)
 -    target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
 -
 -    add_library(${mbedtls_target} SHARED ${src_tls})
--    set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.5.1 SOVERSION 20)
+-    set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.0 SOVERSION 21)
 -    target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
 +    if (BUIILD_X509 OR BUILD_TLS)
 +        add_library(${mbedx509_target} SHARED ${src_x509})
-+        set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.5.1 SOVERSION 6)
++        set_target_properties(${mbedx509_target} PROPERTIES VERSION 3.6.0 SOVERSION 7)
 +        target_link_libraries(${mbedx509_target} PUBLIC ${libs} ${mbedcrypto_target})
 +    endif()
 +    if (BUILD_TLS)
 +        add_library(${mbedtls_target} SHARED ${src_tls})
-+        set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.5.1 SOVERSION 20)
++        set_target_properties(${mbedtls_target} PROPERTIES VERSION 3.6.0 SOVERSION 21)
 +        target_link_libraries(${mbedtls_target} PUBLIC ${libs} ${mbedx509_target})
 +    endif()
  endif(USE_SHARED_MBEDTLS_LIBRARY)
  
  foreach(target IN LISTS target_libraries)
-@@ -349,7 +371,22 @@ endforeach(target)
+@@ -351,7 +373,22 @@ endforeach(target)
  
  set(lib_target "${MBEDTLS_TARGET_PREFIX}lib")
  
@@ -140,5 +140,5 @@
 +    endif()
  endif()
 -- 
-2.34.1
+2.25.1
 
diff --git a/external/MbedTLS/MbedTLS.cmake b/external/MbedTLS/MbedTLS.cmake
index f759e19..a041a8f 100644
--- a/external/MbedTLS/MbedTLS.cmake
+++ b/external/MbedTLS/MbedTLS.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2020-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -7,7 +7,7 @@
 
 set(MBEDTLS_URL "https://github.com/Mbed-TLS/mbedtls.git"
 		CACHE STRING "Mbed TLS repository URL")
-set(MBEDTLS_REFSPEC "mbedtls-3.5.1"
+set(MBEDTLS_REFSPEC "mbedtls-3.6.0"
 		CACHE STRING "Mbed TLS git refspec")
 set(MBEDTLS_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/mbedtls-src"
 		CACHE PATH "MbedTLS source directory")
@@ -32,7 +32,6 @@
 		COMMAND git branch -f bf-am
 		COMMAND git am ${CMAKE_CURRENT_LIST_DIR}/0001-Add-capability-to-selectively-build-libraries.patch
 		COMMAND git reset bf-am
-		COMMAND ${Python3_EXECUTABLE} scripts/config.py crypto
 )
 
 # Only pass libc settings to Mbed TLS if needed. For environments where the standard
diff --git a/external/MbedTLS/config/crypto_posix.h b/external/MbedTLS/config/crypto_posix.h
index eaec37e..9c396bf 100644
--- a/external/MbedTLS/config/crypto_posix.h
+++ b/external/MbedTLS/config/crypto_posix.h
@@ -11,17 +11,30 @@
  * Mbed TLS configuration for using libmbedcrypto in
  * a Posix environment (normal world demo and test applications).
  */
+
+/*
+ * Enable using crypto_config.h, but do not define custom crypto header with
+ * MBEDTLS_PSA_CRYPTO_CONFIG_FILE to enable all the supported algorithms.
+ */
 #define MBEDTLS_PSA_CRYPTO_CONFIG
+
+#define MBEDTLS_BASE64_C
+#define MBEDTLS_BIGNUM_C
+#define MBEDTLS_ECP_NIST_OPTIM
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_HAVE_ASM
+#define MBEDTLS_LMS_C
+#define MBEDTLS_NIST_KW_C
 #define MBEDTLS_NO_UDBL_DIVISION
-#undef MBEDTLS_HAVE_TIME
-#undef MBEDTLS_HAVE_TIME_DATE
-#undef MBEDTLS_FS_IO
-#undef MBEDTLS_SELF_TEST
-#undef MBEDTLS_AESNI_C
-#undef MBEDTLS_PADLOCK_C
-#undef MBEDTLS_PLATFORM_C
-#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
-#undef MBEDTLS_PSA_ITS_FILE_C
-#undef MBEDTLS_TIMING_C
+#define MBEDTLS_OID_C
+#define MBEDTLS_PKCS12_C
+#define MBEDTLS_PKCS5_C
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PK_WRITE_C
+#define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_X509_CRL_PARSE_C
+#define MBEDTLS_X509_CRT_PARSE_C
+#define MBEDTLS_X509_USE_C
 
 #endif /* CONFIG_CRYPTO_POSIX_H */
diff --git a/external/MbedTLS/config/crypto_provider_x509.h b/external/MbedTLS/config/crypto_provider_x509.h
new file mode 100644
index 0000000..979afc7
--- /dev/null
+++ b/external/MbedTLS/config/crypto_provider_x509.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef CONFIG_CRYPTO_PROVIDER_X509_H
+#define CONFIG_CRYPTO_PROVIDER_X509_H
+
+/*
+ * MbedTLS configuration for building libmbedcrypto and libx509 to act as a backend
+ * for the crypto service provider.
+ */
+
+/*
+ * Enable using crypto_config.h, but do not define custom crypto header with
+ * MBEDTLS_PSA_CRYPTO_CONFIG_FILE to enable all the supported algorithms.
+ */
+#define MBEDTLS_PSA_CRYPTO_CONFIG
+
+#define MBEDTLS_BASE64_C
+#define MBEDTLS_BIGNUM_C
+#define MBEDTLS_ECP_NIST_OPTIM
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+#define MBEDTLS_GENPRIME
+#define MBEDTLS_HAVE_ASM
+#define MBEDTLS_LMS_C
+#define MBEDTLS_NIST_KW_C
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_NO_UDBL_DIVISION
+#define MBEDTLS_OID_C
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_PEM_PARSE_C
+#define MBEDTLS_PEM_WRITE_C
+#define MBEDTLS_PKCS12_C
+#define MBEDTLS_PKCS5_C
+#define MBEDTLS_PKCS7_C
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PK_WRITE_C
+#define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_PSA_CRYPTO_STORAGE_C
+#define MBEDTLS_X509_CRL_PARSE_C
+#define MBEDTLS_X509_CRT_PARSE_C
+#define MBEDTLS_X509_USE_C
+
+#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
+#define BACKEND_CRYPTO_API_ADD_PREFIX(f) __mbedtls_backend_##f
+#include "../../../components/service/crypto/backend/prefixed_crypto_api.h"
+
+#endif /* CONFIG_CRYPTO_PROVIDER_X509_H */
diff --git a/external/MbedTLS/config/internal_crypto_smmgw.h b/external/MbedTLS/config/internal_crypto_smmgw.h
new file mode 100644
index 0000000..5d85cf7
--- /dev/null
+++ b/external/MbedTLS/config/internal_crypto_smmgw.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef CONFIG_INTERNAL_CRYPTO_SMMGW_H
+#define CONFIG_INTERNAL_CRYPTO_SMMGW_H
+
+/*
+ * Enable using crypto_config.h, but do not define custom crypto header with
+ * MBEDTLS_PSA_CRYPTO_CONFIG_FILE to enable all the supported algorithms.
+ */
+#define MBEDTLS_PSA_CRYPTO_CONFIG
+
+#define MBEDTLS_BASE64_C
+#define MBEDTLS_BIGNUM_C
+#define MBEDTLS_ENTROPY_C
+#define MBEDTLS_ENTROPY_HARDWARE_ALT
+#define MBEDTLS_HAVE_ASM
+#define MBEDTLS_NO_PLATFORM_ENTROPY
+#define MBEDTLS_NO_UDBL_DIVISION
+#define MBEDTLS_OID_C
+#define MBEDTLS_ASN1_PARSE_C
+#define MBEDTLS_PEM_PARSE_C
+#define MBEDTLS_PEM_WRITE_C
+#define MBEDTLS_PKCS12_C
+#define MBEDTLS_PKCS5_C
+#define MBEDTLS_PKCS7_C
+#define MBEDTLS_PK_C
+#define MBEDTLS_PK_PARSE_C
+#define MBEDTLS_PK_WRITE_C
+#define MBEDTLS_PSA_CRYPTO_C
+#define MBEDTLS_X509_CRL_PARSE_C
+#define MBEDTLS_X509_CRT_PARSE_C
+#define MBEDTLS_X509_USE_C
+
+#endif /* CONFIG_INTERNAL_CRYPTO_SMMGW_H */
diff --git a/external/MbedTLS/config/libmbed_only.h b/external/MbedTLS/config/libmbed_only.h
deleted file mode 100644
index 830f2fa..0000000
--- a/external/MbedTLS/config/libmbed_only.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CONFIG_LIBMBED_ONLY_H
-#define CONFIG_LIBMBED_ONLY_H
-
-#define MBEDTLS_PSA_CRYPTO_CONFIG
-#define MBEDTLS_NO_UDBL_DIVISION
-#undef MBEDTLS_HAVE_TIME
-#undef MBEDTLS_HAVE_TIME_DATE
-#undef MBEDTLS_FS_IO
-#define MBEDTLS_ENTROPY_HARDWARE_ALT
-#define MBEDTLS_NO_PLATFORM_ENTROPY
-#undef MBEDTLS_SELF_TEST
-#undef MBEDTLS_PLATFORM_C
-#undef MBEDTLS_PSA_ITS_FILE_C
-#undef MBEDTLS_TIMING_C
-#undef MBEDTLS_AESNI_C
-#undef MBEDTLS_AESCE_C
-#undef MBEDTLS_PADLOCK_C
-
-#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
-#define BACKEND_CRYPTO_API_ADD_PREFIX(f) __mbedtls_backend_##f
-#include "../../../components/service/crypto/backend/prefixed_crypto_api.h"
-
-#endif /* CONFIG_LIBMBED_ONLY_H */
diff --git a/external/MbedTLS/config/libmbedx509.h b/external/MbedTLS/config/libmbedx509.h
deleted file mode 100644
index 0039d3c..0000000
--- a/external/MbedTLS/config/libmbedx509.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2020-2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CONFIG_LIBMBEDX509_H
-#define CONFIG_LIBMBEDX509_H
-
-/*
- * MbedTLS configuration for building libmbedcrypto and libx509 to act as a backend
- * for the crypto service provider running in an isolated secure processing environment.
- */
-#define MBEDTLS_PSA_CRYPTO_CONFIG
-#define MBEDTLS_NO_UDBL_DIVISION
-#undef MBEDTLS_HAVE_TIME
-#undef MBEDTLS_HAVE_TIME_DATE
-#undef MBEDTLS_FS_IO
-#define MBEDTLS_ENTROPY_HARDWARE_ALT
-#define MBEDTLS_NO_PLATFORM_ENTROPY
-#undef MBEDTLS_SELF_TEST
-#undef MBEDTLS_PLATFORM_C
-#undef MBEDTLS_PSA_ITS_FILE_C
-#undef MBEDTLS_TIMING_C
-#undef MBEDTLS_AESNI_C
-#undef MBEDTLS_AESCE_C
-#undef MBEDTLS_PADLOCK_C
-
-#define MBEDTLS_BIGNUM_C
-#define MBEDTLS_X509_USE_C
-#define MBEDTLS_X509_CRL_PARSE_C
-#define MBEDTLS_X509_CRT_PARSE_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_OID_C
-#define MBEDTLS_ASN1_PARSE_C
-#define MBEDTLS_PKCS7_C
-
-#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER
-#define BACKEND_CRYPTO_API_ADD_PREFIX(f) __mbedtls_backend_##f
-#include "../../../components/service/crypto/backend/prefixed_crypto_api.h"
-
-#endif /* CONFIG_LIBMBEDX509_H */
diff --git a/external/MbedTLS/config/x509_only.h b/external/MbedTLS/config/x509_only.h
deleted file mode 100644
index 5c615fa..0000000
--- a/external/MbedTLS/config/x509_only.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef CONFIG_X509_ONLY_H
-#define CONFIG_X509_ONLY_H
-
-#undef MBEDTLS_LMS_C
-#undef MBEDTLS_HAVE_TIME
-#undef MBEDTLS_HAVE_TIME_DATE
-#undef MBEDTLS_FS_IO
-#undef MBEDTLS_SELF_TEST
-#undef MBEDTLS_AESNI_C
-#undef MBEDTLS_AESCE_C
-#undef MBEDTLS_PADLOCK_C
-#undef MBEDTLS_PLATFORM_C
-#undef MBEDTLS_PSA_CRYPTO_STORAGE_C
-#undef MBEDTLS_PSA_ITS_FILE_C
-#undef MBEDTLS_TIMING_C
-
-#define MBEDTLS_BIGNUM_C
-#define MBEDTLS_X509_USE_C
-#define MBEDTLS_X509_CRL_PARSE_C
-#define MBEDTLS_X509_CRT_PARSE_C
-#define MBEDTLS_PK_PARSE_C
-#define MBEDTLS_OID_C
-#define MBEDTLS_ASN1_PARSE_C
-#define MBEDTLS_PKCS7_C
-
-#endif /* CONFIG_X509_ONLY_H */
diff --git a/external/MbedTLS/mbedtls-init-cache.cmake.in b/external/MbedTLS/mbedtls-init-cache.cmake.in
index c60bbf2..a633781 100644
--- a/external/MbedTLS/mbedtls-init-cache.cmake.in
+++ b/external/MbedTLS/mbedtls-init-cache.cmake.in
@@ -11,8 +11,9 @@
 set(ENABLE_PROGRAMS Off CACHE BOOL "")
 set(ENABLE_TESTING Off CACHE BOOL "")
 set(UNSAFE_BUILD On CACHE BOOL "")
-set(EXTERNAL_DEFINITIONS -DMBEDTLS_USER_CONFIG_FILE="@MBEDTLS_USER_CONFIG_FILE@" CACHE STRING "")
+set(EXTERNAL_DEFINITIONS -DMBEDTLS_CONFIG_FILE="@MBEDTLS_CONFIG_FILE@" CACHE STRING "")
 set(EXTERNAL_INCLUDE_PATHS @MBEDTLS_EXTRA_INCLUDES@ CACHE STRING "")
+set(BRANCH_PROTECTION @BRANCH_PROTECTION@ CACHE STRING "")
 
 set(Python3_EXECUTABLE "@Python3_EXECUTABLE@" CACHE PATH "Location of python3 executable")
 
diff --git a/external/Spdevkit/FindSpdevkit.cmake b/external/Spdevkit/FindSpdevkit.cmake
deleted file mode 100644
index e69de29..0000000
--- a/external/Spdevkit/FindSpdevkit.cmake
+++ /dev/null
diff --git a/external/firmware_test_builder/FirmwareTestBuilder.cmake b/external/firmware_test_builder/FirmwareTestBuilder.cmake
index f5450c6..8f1a819 100644
--- a/external/firmware_test_builder/FirmwareTestBuilder.cmake
+++ b/external/firmware_test_builder/FirmwareTestBuilder.cmake
@@ -8,6 +8,7 @@
 
 set(FIRMWARE_TEST_BUILDER_URL "https://git.trustedfirmware.org/TS/trusted-services.git" CACHE STRING "firmware-test-builder repository URL")
 set(FIRMWARE_TEST_BUILDER_REFSPEC "topics/fwtb" CACHE STRING "firmware-test-builder git refspec")
+set(BRANCH_PROTECTION @BRANCH_PROTECTION@ CACHE STRING "")
 
 set(GIT_OPTIONS
 	GIT_REPOSITORY ${FIRMWARE_TEST_BUILDER_URL}
diff --git a/external/libfdt/fix-strnlen.patch b/external/libfdt/fix-strnlen.patch
deleted file mode 100644
index 7a7bb7d..0000000
--- a/external/libfdt/fix-strnlen.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-This patch enables using libfdt's strlen() implementation.
-
-diff --git i/libfdt/libfdt_env.h w/libfdt/libfdt_env.h
-index 73b6d40..3a2d38c 100644
---- i/libfdt/libfdt_env.h
-+++ w/libfdt/libfdt_env.h
-@@ -66,13 +66,6 @@ static inline fdt64_t cpu_to_fdt64(uint64_t x)
- #undef CPU_TO_FDT16
- #undef EXTRACT_BYTE
-
--#ifdef __APPLE__
--#include <AvailabilityMacros.h>
--
--/* strnlen() is not available on Mac OS < 10.7 */
--# if !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED < \
--                                         MAC_OS_X_VERSION_10_7)
--
- #define strnlen fdt_strnlen
-
- /*
-@@ -88,9 +81,4 @@ static inline size_t fdt_strnlen(const char *string, size_t max_count)
-     return p ? p - string : max_count;
- }
-
--#endif /* !defined(MAC_OS_X_VERSION_10_7) || (MAC_OS_X_VERSION_MAX_ALLOWED <
--          MAC_OS_X_VERSION_10_7) */
--
--#endif /* __APPLE__ */
--
- #endif /* LIBFDT_ENV_H */
diff --git a/external/libfdt/libfdt.cmake b/external/libfdt/libfdt.cmake
index 9da9bba..c3e96f5 100644
--- a/external/libfdt/libfdt.cmake
+++ b/external/libfdt/libfdt.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -18,7 +18,6 @@
 set(GIT_OPTIONS
 	GIT_REPOSITORY ${DTC_URL}
 	GIT_TAG ${DTC_REFSPEC}
-	PATCH_COMMAND git stash COMMAND git apply ${CMAKE_CURRENT_LIST_DIR}/fix-strnlen.patch
 )
 
 include(${TS_ROOT}/tools/cmake/common/LazyFetch.cmake REQUIRED)
diff --git a/external/nanopb/nanopb-init-cache.cmake.in b/external/nanopb/nanopb-init-cache.cmake.in
index c53b6e5..fee5b30 100644
--- a/external/nanopb/nanopb-init-cache.cmake.in
+++ b/external/nanopb/nanopb-init-cache.cmake.in
@@ -12,6 +12,7 @@
 set(nanopb_BUILD_RUNTIME On CACHE BOOL "")
 set(nanopb_BUILD_GENERATOR On CACHE BOOL "")
 set(nanopb_MSVC_STATIC_RUNTIME Off BOOL "")
+set(BRANCH_PROTECTION @BRANCH_PROTECTION@ CACHE STRING "")
 
 # Specify location of python binary and avoid discovery.
 set(Python_EXECUTABLE "@Python_EXECUTABLE@" CACHE PATH "Location of python3 executable")
diff --git a/external/newlib/0001-Allow-aarch64-linux-gcc-to-compile-bare-metal-lib.patch b/external/newlib/0001-Allow-aarch64-linux-gcc-to-compile-bare-metal-lib.patch
deleted file mode 100644
index f87ed5a..0000000
--- a/external/newlib/0001-Allow-aarch64-linux-gcc-to-compile-bare-metal-lib.patch
+++ /dev/null
@@ -1,46 +0,0 @@
-From 64d4a8a9b59ed79bc78658d7edf1bdd9bc4f084d Mon Sep 17 00:00:00 2001
-From: Imre Kis <imre.kis@arm.com>
-Date: Tue, 19 Oct 2021 11:48:10 +0200
-Subject: [PATCH 1/1] Allow aarch64-linux-gcc to compile bare metal lib
-
-Newlib build system determines the target (i.e. Linux, BSD, bare metal,
-etc.) according to the toolchain triplet. This patch changes the
-configure script to treat the aarch64-linux-gnu and the
-aarch64-linux-musl triplets as bare-metal compilers.
-
-Signed-off-by: Imre Kis <imre.kis@arm.com>
-Signed-off-by: Gyorgy Szing <gyorgy.szing@arm.com>
----
- configure                  | 2 +-
- libgloss/aarch64/configure | 2 +-
- 2 files changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/configure b/configure
-index 5db52701..1eb71a80 100755
---- a/configure
-+++ b/configure
-@@ -3659,7 +3659,7 @@ case "${target}" in
-   *-*-freebsd*)
-     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
-     ;;
--  *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
-+  *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
-     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
-     ;;
-   *-*-lynxos*)
-diff --git a/libgloss/aarch64/configure b/libgloss/aarch64/configure
-index b45256f3..25c9d5f7 100755
---- a/libgloss/aarch64/configure
-+++ b/libgloss/aarch64/configure
-@@ -2521,7 +2521,7 @@ test "${CCASFLAGS+set}" = set || CCASFLAGS=$CFLAGS
- 
- 
- case "${target}" in
--  *-*-elf)
-+  *-*-elf | *-linux-gnu | *-linux-musl)
- 	objtype=elf-
- 	;;
- esac
--- 
-2.17.1
-
diff --git a/external/newlib/0002-Disable-unnecessary-targets.patch b/external/newlib/0002-Disable-unnecessary-targets.patch
deleted file mode 100644
index 61f1813..0000000
--- a/external/newlib/0002-Disable-unnecessary-targets.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From a8c7c58679126dd4c75538aeedfee0c501df6548 Mon Sep 17 00:00:00 2001
-From: Anton Antonov <anton.antonov@arm.com>
-Date: Mon, 19 Sep 2022 23:37:31 +0200
-Subject: [PATCH 2/2] Disable unnecessary targets
-
-For Trusted Services we require only newlib and libgloss built for
-target. We don't need to build any host tools and we can use a
-cross-compiler only. This patch removes skipping newlib and libgloss for
-this case.
-
-Signed-off-by: Anton Antonov <anton.antonov@arm.com>
----
- configure | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/configure b/configure
-index 1eb71a806..dce91609e 100755
---- a/configure
-+++ b/configure
-@@ -2886,7 +2886,7 @@ esac
- 
- # Some are only suitable for cross toolchains.
- # Remove these if host=target.
--cross_only="target-libgloss target-newlib target-opcodes"
-+cross_only="target-opcodes"
- 
- case $is_cross_compiler in
-   no) skipdirs="${skipdirs} ${cross_only}" ;;
--- 
-2.37.0.windows.1
-
diff --git a/external/newlib/newlib.cmake b/external/newlib/newlib.cmake
deleted file mode 100644
index 3a0eb23..0000000
--- a/external/newlib/newlib.cmake
+++ /dev/null
@@ -1,269 +0,0 @@
-#-------------------------------------------------------------------------------
-# Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
-#
-# SPDX-License-Identifier: BSD-3-Clause
-#
-#-------------------------------------------------------------------------------
-
-# Add newlib specific porting files to the project.
-if (NOT DEFINED TGT)
-	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
-endif()
-
-# Adding libc interface
-add_components(TARGET ${TGT}
-	BASE_DIR ${TS_ROOT}
-	COMPONENTS
-		components/common/libc
-)
-
-# Compile TS specific newlib porting files.
-target_sources(${TGT} PRIVATE
-	"${CMAKE_CURRENT_LIST_DIR}/newlib_init.c"
-	"${CMAKE_CURRENT_LIST_DIR}/newlib_sp_assert.c"
-	"${CMAKE_CURRENT_LIST_DIR}/newlib_sp_heap.c"
-)
-
-# Fetch newlib from external repository
-set(NEWLIB_URL "https://sourceware.org/git/newlib-cygwin.git"
-		CACHE STRING "newlib repository URL")
-set(NEWLIB_REFSPEC "newlib-4.1.0"
-		CACHE STRING "newlib git refspec")
-set(NEWLIB_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/newlib-src"
-		CACHE PATH "newlib source-code location")
-set(NEWLIB_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/newlib_install"
-		CACHE PATH "newlib installation directory")
-# Supported build types: "Release" "Debug" "RelWithDebInfo" "Off"
-# If set to "Off" -DNEWLIB_CFLAGS_TARGET can be used to set compiler
-# switches from the command line.
-set(NEWLIB_BUILD_TYPE "Release"	CACHE STRING "newlib build type")
-
-# Extracting compiler prefix without the trailing hyphen from the C compiler name
-get_filename_component(COMPILER_PATH ${CMAKE_C_COMPILER} DIRECTORY)
-get_filename_component(COMPILER_NAME ${CMAKE_C_COMPILER} NAME)
-string(REGEX REPLACE "(.*)-[^-]+$" "\\1" COMPILER_PREFIX ${COMPILER_NAME})
-
-find_library(NEWLIB_LIBC_PATH
-				NAMES libc.a c.a libc.lib c.lib
-				PATHS ${NEWLIB_INSTALL_DIR}
-				PATH_SUFFIXES "${COMPILER_PREFIX}/lib"
-				DOC "Location of newlib::libc library."
-				NO_DEFAULT_PATH
-)
-set(NEWLIB_LIBC_PATH ${NEWLIB_LIBC_PATH})
-unset(NEWLIB_LIBC_PATH CACHE)
-
-find_library(NEWLIB_LIBNOSYS_PATH
-				NAMES libnosys.a nosys.a nosys.lib nosys.lib
-				PATHS ${NEWLIB_INSTALL_DIR}
-				PATH_SUFFIXES "${COMPILER_PREFIX}/lib"
-				DOC "Location of newlib::libnosys library."
-				NO_DEFAULT_PATH
-)
-set(NEWLIB_LIBNOSYS_PATH ${NEWLIB_LIBNOSYS_PATH})
-unset(NEWLIB_LIBNOSYS_PATH CACHE)
-
-# libc - get compiler specific configuration from GCC
-add_library(c STATIC IMPORTED)
-# We need "freestandig" mode. Ask the compile to do the needed configurations.
-include(${TS_ROOT}/tools/cmake/compiler/GCC.cmake)
-compiler_set_freestanding(TARGET c)
-
-if (NOT NEWLIB_LIBC_PATH)
-	# Determine the number of processes to run while running parallel builds.
-	# Pass -DPROCESSOR_COUNT=<n> to cmake to override.
-	if(NOT DEFINED PROCESSOR_COUNT)
-		include(ProcessorCount)
-		ProcessorCount(PROCESSOR_COUNT)
-		set(PROCESSOR_COUNT ${PROCESSOR_COUNT}
-				CACHE STRING "Number of cores to use for parallel builds.")
-	endif()
-
-	# See if the source is available locally
-	find_file(NEWLIB_HEADER_FILE
-		NAMES newlib.h
-		PATHS ${NEWLIB_SOURCE_DIR}
-		PATH_SUFFIXES "newlib/libc/include"
-		NO_DEFAULT_PATH
-	)
-	set(NEWLIB_HEADER_FILE ${NEWLIB_HEADER_FILE})
-	unset(NEWLIB_HEADER_FILE CACHE)
-
-	# Source not found, fetch it.
-	if (NOT NEWLIB_HEADER_FILE)
-		include(FetchContent)
-
-		# Checking git
-		find_program(GIT_COMMAND "git")
-		if (NOT GIT_COMMAND)
-			message(FATAL_ERROR "Please install git")
-		endif()
-
-		# List patch files.
-		file(GLOB _patch_files LIST_DIRECTORIES false "${CMAKE_CURRENT_LIST_DIR}/[0-9]*-[!0-9]*.patch")
-		# Sort items in natural order to ensure patches are amended in the right order.
-		list(SORT _patch_files COMPARE NATURAL)
-		# Convert the list to a string of concatenated quoted list items.
-		string(REPLACE ";" "\" \"" _patch_files "${_patch_files}")
-		set(_patch_files "\"${_patch_files}\"")
-		# Create a shell script patching newlib with the files listed above
-		string(APPEND _patch_script "#!/bin/sh\n"
-			" ${GIT_COMMAND} stash\n"
-			" ${GIT_COMMAND} branch ts-bf-am\n"
-			" ${GIT_COMMAND} am ${_patch_files}\n"
-			" ${GIT_COMMAND} reset ts-bf-am\n"
-			" ${GIT_COMMAND} branch -D ts-bf-am\n"
-		)
-		file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/patch-newlib "${_patch_script}")
-
-		# Fetching newlib
-		FetchContent_Declare(
-			newlib
-			SOURCE_DIR ${NEWLIB_SOURCE_DIR}
-			GIT_REPOSITORY ${NEWLIB_URL}
-			GIT_TAG ${NEWLIB_REFSPEC}
-			GIT_SHALLOW FALSE
-			PATCH_COMMAND sh ${CMAKE_CURRENT_BINARY_DIR}/patch-newlib
-		)
-
-		# FetchContent_GetProperties exports newlib_SOURCE_DIR and newlib_BINARY_DIR variables
-		FetchContent_GetProperties(newlib)
-		# FetchContent_Populate will fail if the source directory is removed since it will try to
-		# do an "update" and not a "populate" action. As a workaround, remove the subbuild directory.
-		# Note: this fix assumes, the default subbuild location is used.
-		file(REMOVE_RECURSE "${CMAKE_CURRENT_BINARY_DIR}/_deps/newlib-subbuild")
-
-		if(NOT newlib_POPULATED)
-			message(STATUS "Fetching newlib")
-			FetchContent_Populate(newlib)
-		endif()
-		set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${NEWLIB_SOURCE_DIR})
-	endif()
-
-	# Get NEWLIB_EXTRA_PARAMS value from environment
-	set(NEWLIB_EXTRA_PARAMS $ENV{NEWLIB_EXTRA_PARAMS} CACHE STRING "")
-
-	# Split a newlib extra build parameter into a list of parameters
-	set(_extra_params ${NEWLIB_EXTRA_PARAMS})
-	separate_arguments(_extra_params)
-
-	# Transfer libgcc specific settings to newlib, and set position independent compilation
-	string(REPLACE ";" " -I" _more_cflags_target "${LIBGCC_INCLUDE_DIRS}" )
-	set(_more_cflags_target "-fpic -I${_more_cflags_target}")
-
-	string(TOUPPER ${NEWLIB_BUILD_TYPE} UC_NEWLIB_BUILD_TYPE)
-	if ("${UC_NEWLIB_BUILD_TYPE}" STREQUAL "DEBUG")
-		set(_more_cflags_target "${_more_cflags_target} -g -O0")
-	elseif ("${UC_NEWLIB_BUILD_TYPE}" STREQUAL "RELEASE")
-		set(_more_cflags_target "${_more_cflags_target} -O2")
-	elseif ("${UC_NEWLIB_BUILD_TYPE}" STREQUAL "RELWITHDEBINFO")
-		set(_more_cflags_target "${_more_cflags_target} -g -O2")
-	elseif (NOT "${UC_NEWLIB_BUILD_TYPE}" STREQUAL "OFF")
-		message(FATAL_ERROR "unsupported build type to newlib.")
-	endif()
-
-	# Get external extra flags for target from environment.
-	set(NEWLIB_CFLAGS_TARGET $ENV{NEWLIB_CFLAGS_TARGET} CACHE STRING "")
-
-	# Merge our CFLAGS with external CFLAGS
-	if (NOT "${NEWLIB_CFLAGS_TARGET}" STREQUAL "")
-		# Add a space separator if external value is not empty
-		string(APPEND NEWLIB_CFLAGS_TARGET " ")
-	endif()
-	# Concatenate, and override CACHE value
-	set(NEWLIB_CFLAGS_TARGET "${NEWLIB_CFLAGS_TARGET}${_more_cflags_target}" CACHE STRING "" FORCE)
-
-	# Get extra external CFLAGS for host from environment
-	set(NEWLIB_CFLAGS $ENV{NEWLIB_CFLAGS} CACHE STRING "")
-
-	# Newlib is keeping build artifacts in the source directory. If the source is pre-fetched,
-	# intermediate files of previoud build migth be still present.
-	# Run distclean to avoid build errors due to reconfiguration.
-	execute_process(COMMAND
-		${CMAKE_COMMAND} -E env --unset=CC PATH=${COMPILER_PATH}:$ENV{PATH}
-			make -j${PROCESSOR_COUNT} distclean
-		WORKING_DIRECTORY
-			${NEWLIB_SOURCE_DIR}
-		RESULT_VARIABLE _newlib_error
-	)
-	#ignore error as distclean-host is failing.
-	#if (_newlib_error)
-	#	message(FATAL_ERROR "\"distclean\" step of newlib failed with ${_newlib_error}.")
-	#endif()
-
-	# Newlib configure step
-	# CC env var must be unset otherwise configure will assume the cross compiler is the host
-	# compiler.
-	# The configure options are set to minimize code size and memory usage.
-	execute_process(COMMAND
-		${CMAKE_COMMAND} -E env --unset=CC PATH=${COMPILER_PATH}:$ENV{PATH} ./configure
-			--target=${COMPILER_PREFIX}
-			--host=${COMPILER_PREFIX}
-			--prefix=${NEWLIB_INSTALL_DIR}
-			--enable-newlib-nano-formatted-io
-			--enable-newlib-nano-malloc
-			--enable-lite-exit
-			--enable-newlib-reent-small
-			--enable-newlib-global-atexit
-			--disable-multilib
-			${_extra_params}
-			CFLAGS_FOR_TARGET=${NEWLIB_CFLAGS_TARGET}
-			CFLAGS=${NEWLIB_CFLAGS}
-			LDFLAGS_FOR_TARGET=-fpie
-		WORKING_DIRECTORY
-			${NEWLIB_SOURCE_DIR}
-		RESULT_VARIABLE _newlib_error
-	)
-
-	if (_newlib_error)
-		message(FATAL_ERROR "Configuration step of newlib failed with ${_newlib_error}.")
-	endif()
-
-	# Newlib build step
-	execute_process(COMMAND
-		${CMAKE_COMMAND} -E env --unset=CC PATH=${COMPILER_PATH}:$ENV{PATH}
-			make -j${PROCESSOR_COUNT}
-		WORKING_DIRECTORY
-			${NEWLIB_SOURCE_DIR}
-		RESULT_VARIABLE _newlib_error
-	)
-
-	if (_newlib_error)
-		message(FATAL_ERROR "Build step of newlib failed with ${_newlib_error}.")
-	endif()
-
-	# Newlib install step
-	execute_process(COMMAND
-		${CMAKE_COMMAND} -E env --unset=CC PATH=${COMPILER_PATH}:$ENV{PATH} make install
-		WORKING_DIRECTORY
-			${NEWLIB_SOURCE_DIR}
-		RESULT_VARIABLE _newlib_error
-	)
-
-	if (_newlib_error)
-		message(FATAL_ERROR "Install step of newlib failed with ${_newlib_error}.")
-	endif()
-
-	set(NEWLIB_LIBC_PATH "${NEWLIB_INSTALL_DIR}/${COMPILER_PREFIX}/lib/libc.a")
-	set(NEWLIB_LIBNOSYS_PATH "${NEWLIB_INSTALL_DIR}/${COMPILER_PREFIX}/lib/libnosys.a")
-endif()
-
-set_property(DIRECTORY ${CMAKE_SOURCE_DIR}
-	APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${NEWLIB_LIBC_PATH})
-
-# libc - continue configuration
-set_property(TARGET c PROPERTY IMPORTED_LOCATION "${NEWLIB_LIBC_PATH}")
-target_compile_definitions(c INTERFACE ENABLE_CDEFSH_FIX)
-set_property(TARGET c PROPERTY
-		INTERFACE_INCLUDE_DIRECTORIES "${NEWLIB_INSTALL_DIR}/${COMPILER_PREFIX}/include")
-
-# Make standard library available in the build system.
-add_library(stdlib::c ALIAS c)
-
-# libnosys
-add_library(nosys STATIC IMPORTED)
-set_property(TARGET nosys PROPERTY IMPORTED_LOCATION "${NEWLIB_LIBNOSYS_PATH}")
-set_property(TARGET nosys PROPERTY
-		INTERFACE_INCLUDE_DIRECTORIES "${NEWLIB_INSTALL_DIR}/${COMPILER_PREFIX}/include")
-compiler_set_freestanding(TARGET nosys)
-target_link_libraries(c INTERFACE nosys)
diff --git a/external/newlib/newlib_init.c b/external/newlib/newlib_init.c
deleted file mode 100644
index 9450a68..0000000
--- a/external/newlib/newlib_init.c
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-/*
- * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved.
- */
-
-#include "libc_init.h"
-
-/* Comes from libc */
-void __libc_init_array(void);
-
-void _init(void)
-{
-	/* Dummy */
-}
-
-void libc_init(void)
-{
-	/* Initializing global variables, calling constructors */
-	__libc_init_array();
-}
diff --git a/external/newlib/newlib_sp_assert.c b/external/newlib/newlib_sp_assert.c
deleted file mode 100644
index f386bb4..0000000
--- a/external/newlib/newlib_sp_assert.c
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-/*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
- */
-
-#include "assert_fail_handler.h"
-#include "compiler.h"
-#include <assert.h>
-
-/*
- * This function implements newlib's assert fail handler function by calling the
- * generic assert fail handler function that should be implemented by the
- * environment.
- */
-void __noreturn __assert_func(const char *file, int line, const char *func,
-			      const char *failedexpr)
-{
-	assert_fail_handler(file, line, func, failedexpr);
-	while (1)
-		;
-}
diff --git a/external/newlib/newlib_sp_heap.c b/external/newlib/newlib_sp_heap.c
deleted file mode 100644
index 20b9ce3..0000000
--- a/external/newlib/newlib_sp_heap.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: BSD-3-Clause
-/*
- * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
- */
-
-#include "compiler.h"
-#include <errno.h>
-#include <stdint.h>
-#include <unistd.h>
-
-/* Allocating heap area */
-#ifndef SP_HEAP_SIZE
-#error "SP_HEAP_SIZE is undefined, please define it in the build system"
-#endif
-
-static uint8_t sp_heap[SP_HEAP_SIZE] __aligned(16);
-static uint8_t *program_break = sp_heap;
-
-/**
- * Basic sbrk implementation which increases the program break through the
- * sp_heap buffer.
- */
-void *_sbrk(ptrdiff_t incr)
-{
-	uint8_t *previous_break = program_break;
-	uint8_t *new_break = program_break + incr;
-
-	if ((new_break < sp_heap) || (new_break > (sp_heap + sizeof(sp_heap)))) {
-		errno = ENOMEM;
-		return (void *)(uintptr_t) -1;
-	}
-
-	program_break += incr;
-
-	return (void *) previous_break;
-}
diff --git a/external/psa_arch_tests/psa-arch-test-init-cache.cmake.in b/external/psa_arch_tests/psa-arch-test-init-cache.cmake.in
index 5e227a5..a6934eb 100644
--- a/external/psa_arch_tests/psa-arch-test-init-cache.cmake.in
+++ b/external/psa_arch_tests/psa-arch-test-init-cache.cmake.in
@@ -13,6 +13,7 @@
 set(ARCH_TEST_EXTERNAL_DEFS "@PSA_ARCH_TEST_EXTERNAL_DEFS@"  CACHE STRING "")
 set(CMAKE_VERBOSE_MAKEFILE OFF CACHE BOOL "")
 set(TARGET "tgt_dev_apis_linux"  CACHE STRING "")
+set(BRANCH_PROTECTION @BRANCH_PROTECTION@ CACHE STRING "")
 
 # Pass comand line paramter passed to the TS deployment configuration time over to psa-acs build.
 if(NOT "@PSA_TARGET_QCBOR@" STREQUAL "")
diff --git a/external/qcbor/qcbor-init-cache.cmake.in b/external/qcbor/qcbor-init-cache.cmake.in
index 88afecf..9b61cab 100644
--- a/external/qcbor/qcbor-init-cache.cmake.in
+++ b/external/qcbor/qcbor-init-cache.cmake.in
@@ -7,6 +7,7 @@
 
 set(CMAKE_INSTALL_PREFIX "@BUILD_INSTALL_DIR@" CACHE STRING "")
 set(CMAKE_TOOLCHAIN_FILE "@TS_EXTERNAL_LIB_TOOLCHAIN_FILE@" CACHE STRING "")
+set(BRANCH_PROTECTION @BRANCH_PROTECTION@ CACHE STRING "")
 
 # Determine floating point configuration
 set(TS_NO_FLOAT_HW "@TS_NO_FLOAT_HW@")
diff --git a/external/t_cose/t_cose-init-cache.cmake.in b/external/t_cose/t_cose-init-cache.cmake.in
index abd3eba..01f3f16 100644
--- a/external/t_cose/t_cose-init-cache.cmake.in
+++ b/external/t_cose/t_cose-init-cache.cmake.in
@@ -7,6 +7,7 @@
 
 set(CMAKE_INSTALL_PREFIX "@BUILD_INSTALL_DIR@" CACHE STRING "")
 set(CMAKE_TOOLCHAIN_FILE "@TS_EXTERNAL_LIB_TOOLCHAIN_FILE@" CACHE STRING "")
+set(BRANCH_PROTECTION @BRANCH_PROTECTION@ CACHE STRING "")
 
 set(MBEDTLS On CACHE STRING "")
 
diff --git a/external/tf_a/include/cdefs.h b/external/tf_a/include/cdefs.h
index e52b60a..54ab732 100644
--- a/external/tf_a/include/cdefs.h
+++ b/external/tf_a/include/cdefs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -9,8 +9,8 @@
 
 /**
  * Some tf-a files assume that <cdefs.h> is in the global include path. This
- * provides an alternative using common/utils/compiler.h.
+ * provides an alternative using components/common/libc/include/cdefs.h.
  */
-#include <compiler.h>
+#include <components/common/libc/include/cdefs.h>
 
 #endif /* TF_A_CDEFS_H */
diff --git a/external/tf_a/tf-a.cmake b/external/tf_a/tf-a.cmake
index a7a28f8..6a2d2ad 100644
--- a/external/tf_a/tf-a.cmake
+++ b/external/tf_a/tf-a.cmake
@@ -59,4 +59,10 @@
 	target_include_directories(${MY_PARAMS_TARGET} PRIVATE "${TFA_SOURCE_DIR}/include")
 	target_include_directories(${MY_PARAMS_TARGET} PRIVATE "${TFA_SOURCE_DIR}/include/arch/aarch64")
 
+	# Disable assertions in TF-A for release builds
+	if ("${UC_CMAKE_BUILD_TYPE}" STREQUAL "MINSIZEREL" OR
+		"${UC_CMAKE_BUILD_TYPE}" STREQUAL "RELEASE" OR
+		"${UC_CMAKE_BUILD_TYPE}" STREQUAL "RELWITHDEBINFO")
+    	target_compile_definitions(${MY_PARAMS_TARGET} PRIVATE "ENABLE_ASSERTIONS=0")
+	endif()
 endfunction()
\ No newline at end of file
diff --git a/platform/providers/arm/corstone1000/platform.cmake b/platform/providers/arm/corstone1000/platform.cmake
index d944acf..d39b790 100644
--- a/platform/providers/arm/corstone1000/platform.cmake
+++ b/platform/providers/arm/corstone1000/platform.cmake
@@ -12,7 +12,7 @@
 
 target_compile_definitions(${TGT} PRIVATE
 	SMM_VARIABLE_INDEX_STORAGE_UID=0x787
-	PLAT_RSS_COMMS_PAYLOAD_MAX_SIZE=0x2080
+	PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE=0x2080
 	COMMS_MHU_MSG_SIZE=0x3500
 )
 
diff --git a/platform/providers/arm/total_compute/platform.cmake b/platform/providers/arm/total_compute/platform.cmake
new file mode 100644
index 0000000..26e27f7
--- /dev/null
+++ b/platform/providers/arm/total_compute/platform.cmake
@@ -0,0 +1,23 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2023, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+# Platform definition for the 'total_compute' virtual platform.
+#-------------------------------------------------------------------------------
+if (NOT DEFINED TGT)
+	message(FATAL_ERROR "mandatory parameter TGT is not defined.")
+endif()
+
+get_property(_platform_driver_dependencies TARGET ${TGT}
+	PROPERTY TS_PLATFORM_DRIVER_DEPENDENCIES
+)
+
+#-------------------------------------------------------------------------------
+#  Map platform dependencies to suitable drivers for this platform
+#
+#  Currently using mock drivers.  TODO: enable hardware TRNG for TC
+#-------------------------------------------------------------------------------
+if ("trng" IN_LIST _platform_driver_dependencies)
+	target_sources(${TGT} PRIVATE "${TS_ROOT}/platform/drivers/mock/mock_trng.c")
+endif()
diff --git a/protocols/common/efi/efi_types.h b/protocols/common/efi/efi_types.h
index f37848b..2bbcf94 100644
--- a/protocols/common/efi/efi_types.h
+++ b/protocols/common/efi/efi_types.h
@@ -7,7 +7,9 @@
 #ifndef COMMON_EFI_TYPES_H
 #define COMMON_EFI_TYPES_H
 
+#include <stdbool.h>
 #include <stdint.h>
+#include <string.h>
 
 /**
  * Common EFI types
@@ -56,4 +58,15 @@
 #define EFI_MM_COMMUNICATE_HEADER_SIZE	\
 	(offsetof(EFI_MM_COMMUNICATE_HEADER, Data))
 
+/*
+ * Returns whether the two guid-s equal. To avoid structure padding related error
+ * the fields are checked separately instead of memcmp.
+ */
+static inline bool compare_guid(const EFI_GUID *guid1, const EFI_GUID *guid2)
+{
+	return guid1->Data1 == guid2->Data1 && guid1->Data2 == guid2->Data2 &&
+	       guid1->Data3 == guid2->Data3 &&
+	       !memcmp(&guid1->Data4, &guid2->Data4, sizeof(guid1->Data4));
+}
+
 #endif /* COMMON_EFI_TYPES_H */
diff --git a/protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h b/protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h
new file mode 100644
index 0000000..29964b3
--- /dev/null
+++ b/protocols/service/crypto/packed-c/get_uefi_priv_auth_var_fingerprint.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+#define TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H
+
+#include <stdint.h>
+
+/* Variable length output parameter tags */
+enum {
+	TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_OUT_TAG_IDENTIFIER = 1,
+};
+
+/* Variable length input parameter tags */
+enum {
+	TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_IN_TAG_SIGNATURE = 1,
+};
+
+#endif /* TS_CRYPTO_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT_H */
diff --git a/protocols/service/crypto/packed-c/opcodes.h b/protocols/service/crypto/packed-c/opcodes.h
index 35b8159..8bc2b49 100644
--- a/protocols/service/crypto/packed-c/opcodes.h
+++ b/protocols/service/crypto/packed-c/opcodes.h
@@ -28,6 +28,7 @@
 #define TS_CRYPTO_OPCODE_SIGN_MESSAGE           (TS_CRYPTO_OPCODE_BASE + 16)
 #define TS_CRYPTO_OPCODE_VERIFY_MESSAGE         (TS_CRYPTO_OPCODE_BASE + 17)
 #define TS_CRYPTO_OPCODE_VERIFY_PKCS7_SIGNATURE (TS_CRYPTO_OPCODE_BASE + 18)
+#define TS_CRYPTO_OPCODE_GET_UEFI_PRIV_AUTH_VAR_FINGERPRINT (TS_CRYPTO_OPCODE_BASE + 19)
 
 /* Hash operations */
 #define TS_CRYPTO_OPCODE_HASH_BASE              (0x0200)
diff --git a/protocols/service/fwu/fwu_proto.h b/protocols/service/fwu/fwu_proto.h
new file mode 100644
index 0000000..4bcacb1
--- /dev/null
+++ b/protocols/service/fwu/fwu_proto.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FWU_PROTO_H
+#define FWU_PROTO_H
+
+#include <stdint.h>
+
+#include "opcodes.h"
+#include "protocols/common/osf/uuid.h"
+#include "status.h"
+
+/**
+ * The major version number of the FWU-A access protocol. It will be incremented
+ * on significant updates that may include breaking changes.
+ */
+#define FWU_PROTOCOL_VERSION_MAJOR 1
+
+/**
+ * The minor version number  It will be incremented in
+ * small updates that are unlikely to include breaking changes.
+ */
+#define FWU_PROTOCOL_VERSION_MINOR 0
+
+/**
+ * Protocol GUIDs defined in FWU-A specification
+ */
+#define FWU_UPDATE_AGENT_CANONICAL_UUID "6823a838-1b06-470e-9774-0cce8bfb53fd"
+#define FWU_DIRECTORY_CANONICAL_UUID	"deee58d9-5147-4ad3-a290-77666e2341a5"
+#define FWU_METADATA_CANONICAL_UUID	"8a7a84a0-8387-40f6-ab41-a8b9a5a60d23"
+
+#define FWU_OPEN_OP_TYPE_READ  (0)
+#define FWU_OPEN_OP_TYPE_WRITE (1)
+
+/**
+ * Image directory
+ */
+#define FWU_IMAGE_DIRECTORY_VERSION	(2)
+
+struct __attribute__((__packed__)) fwu_image_info_entry {
+	uint8_t img_type_uuid[OSF_UUID_OCTET_LEN];
+	uint32_t client_permissions;
+	uint32_t img_max_size;
+	uint32_t lowest_accepted_version;
+	uint32_t img_version;
+	uint32_t accepted;
+	uint32_t reserved;
+};
+
+struct __attribute__((__packed__)) fwu_image_directory {
+	uint32_t directory_version;
+	uint32_t img_info_offset;
+	uint32_t num_images;
+	uint32_t correct_boot;
+	uint32_t img_info_size;
+	uint32_t reserved;
+	struct fwu_image_info_entry img_info_entry[];
+};
+
+/**
+ * Message parameters
+ */
+
+struct __attribute__((__packed__)) fwu_request_header {
+	uint32_t func_id;
+	uint8_t payload[];
+};
+
+struct __attribute__((__packed__)) fwu_response_header {
+	uint32_t status;
+	uint8_t payload[];
+};
+
+struct __attribute__((__packed__)) fwu_discover_out {
+	int16_t service_status;
+	uint8_t version_major;
+	uint8_t version_minor;
+	uint16_t off_function_presence;
+	uint16_t num_func;
+	uint64_t max_payload_size;
+	uint32_t flags;
+	uint32_t vendor_specific_flags;
+	uint8_t function_presence[];
+};
+
+struct __attribute__((__packed__)) fwu_begin_staging_in {
+	uint32_t reserved;
+	uint32_t vendor_flags;
+	uint32_t partial_update_count;
+	uint8_t update_guid[];
+};
+
+struct __attribute__((__packed__)) fwu_open_in {
+	uint8_t image_type_uuid[OSF_UUID_OCTET_LEN];
+	uint8_t op_type;
+};
+
+struct __attribute__((__packed__)) fwu_open_out {
+	uint32_t handle;
+};
+
+struct __attribute__((__packed__)) fwu_write_stream_in {
+	uint32_t handle;
+	uint32_t data_len;
+	uint8_t payload[];
+};
+
+struct __attribute__((__packed__)) fwu_read_stream_in {
+	uint32_t handle;
+};
+
+struct __attribute__((__packed__)) fwu_read_stream_out {
+	uint32_t read_bytes;
+	uint32_t total_bytes;
+	uint8_t payload[];
+};
+
+struct __attribute__((__packed__)) fwu_commit_in {
+	uint32_t handle;
+	uint32_t acceptance_req;
+	uint32_t max_atomic_len;
+};
+
+struct __attribute__((__packed__)) fwu_commit_out {
+	uint32_t progress;
+	uint32_t total_work;
+};
+
+struct __attribute__((__packed__)) fwu_accept_image_in {
+	uint32_t reserved;
+	uint8_t image_type_uuid[OSF_UUID_OCTET_LEN];
+};
+
+#endif /* FWU_PROTO_H */
diff --git a/protocols/service/fwu/packed-c/metadata.h b/protocols/service/fwu/metadata.h
similarity index 100%
rename from protocols/service/fwu/packed-c/metadata.h
rename to protocols/service/fwu/metadata.h
diff --git a/protocols/service/fwu/packed-c/metadata_v1.h b/protocols/service/fwu/metadata_v1.h
similarity index 100%
rename from protocols/service/fwu/packed-c/metadata_v1.h
rename to protocols/service/fwu/metadata_v1.h
diff --git a/protocols/service/fwu/packed-c/metadata_v2.h b/protocols/service/fwu/metadata_v2.h
similarity index 91%
rename from protocols/service/fwu/packed-c/metadata_v2.h
rename to protocols/service/fwu/metadata_v2.h
index 33efb33..7993681 100644
--- a/protocols/service/fwu/packed-c/metadata_v2.h
+++ b/protocols/service/fwu/metadata_v2.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Arm Limited. All rights reserved.
+ * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -35,20 +35,24 @@
 	/* Metadata version */
 	uint32_t version;
 
+	/* Active bank index as directed by update agent [0..n] */
+	uint32_t active_index;
+
+	/* Previous active bank index [0..n] */
+	uint32_t previous_active_index;
+
 	/* The overall metadata size */
 	uint32_t metadata_size;
 
 	/* The size in bytes of the fixed size header */
-	uint16_t header_size;
+	uint16_t descriptor_offset;
 
-	/* Active bank index as directed by update agent [0..n] */
-	uint8_t active_index;
-
-	/* Previous active bank index [0..n] */
-	uint8_t previous_active_index;
+	uint16_t reserved_16;
 
 	/* Bank state bitmaps */
 	uint8_t bank_state[FWU_METADATA_V2_NUM_BANK_STATES];
+
+	uint32_t reserved_1c;
 };
 
 /* Properties of image in a bank */
@@ -91,6 +95,8 @@
 	/* Number of banks */
 	uint8_t num_banks;
 
+	uint8_t reserved_01;
+
 	/* Number of images listed in the img_entry array */
 	uint16_t num_images;
 
@@ -98,7 +104,7 @@
 	uint16_t img_entry_size;
 
 	/* The size of bytes of the bank_entry data structure */
-	uint16_t bank_entry_size;
+	uint16_t bank_info_entry_size;
 
 	/* Array of image_entry structures */
 	struct fwu_image_entry img_entry[];
diff --git a/protocols/service/fwu/opcodes.h b/protocols/service/fwu/opcodes.h
new file mode 100644
index 0000000..d6bbf3d
--- /dev/null
+++ b/protocols/service/fwu/opcodes.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2022-2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef FWU_PROTO_OPCODES_H
+#define FWU_PROTO_OPCODES_H
+
+/**
+ * Service-level opcodes
+ */
+#define FWU_FUNC_ID_DISCOVER		(0)
+#define FWU_FUNC_ID_BEGIN_STAGING	(16)
+#define FWU_FUNC_ID_END_STAGING	(17)
+#define FWU_FUNC_ID_CANCEL_STAGING	(18)
+#define FWU_FUNC_ID_OPEN		(19)
+#define FWU_FUNC_ID_WRITE_STREAM	(20)
+#define FWU_FUNC_ID_READ_STREAM	(21)
+#define FWU_FUNC_ID_COMMIT		(22)
+#define FWU_FUNC_ID_ACCEPT_IMAGE	(23)
+#define FWU_FUNC_ID_SELECT_PREVIOUS	(24)
+
+#define FWU_FUNC_ID_COUNT		(10)
+
+#endif /* FWU_PROTO_OPCODES_H */
diff --git a/protocols/service/fwu/packed-c/fwu_proto.h b/protocols/service/fwu/packed-c/fwu_proto.h
deleted file mode 100644
index 6cd691a..0000000
--- a/protocols/service/fwu/packed-c/fwu_proto.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2022-2023, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FWU_PROTO_H
-#define FWU_PROTO_H
-
-#include <stdint.h>
-
-#include "opcodes.h"
-#include "protocols/common/osf/uuid.h"
-#include "status.h"
-
-/**
- * The major version number of the FWU-A access protocol. It will be incremented
- * on significant updates that may include breaking changes.
- */
-#define FWU_PROTOCOL_VERSION_MAJOR 2
-
-/**
- * The minor version number  It will be incremented in
- * small updates that are unlikely to include breaking changes.
- */
-#define FWU_PROTOCOL_VERSION_MINOR 0
-
-/**
- * Protocol GUIDs defined in FWU-A specification
- */
-#define FWU_UPDATE_AGENT_CANONICAL_UUID "6823a838-1b06-470e-9774-0cce8bfb53fd"
-#define FWU_DIRECTORY_CANONICAL_UUID	"deee58d9-5147-4ad3-a290-77666e2341a5"
-#define FWU_METADATA_CANONICAL_UUID	"8a7a84a0-8387-40f6-ab41-a8b9a5a60d23"
-
-/**
- * Image directory
- */
-#define FWU_READ_PERM  (1u << 1)
-#define FWU_WRITE_PERM (1u << 0)
-
-struct __attribute__((__packed__)) ts_fwu_image_info_entry {
-	uint8_t img_type_uuid[OSF_UUID_OCTET_LEN];
-	uint32_t client_permissions;
-	uint32_t img_max_size;
-	uint32_t lowest_accepted_version;
-	uint32_t img_version;
-	uint32_t accepted;
-	uint32_t reserved;
-};
-
-struct __attribute__((__packed__)) ts_fwu_image_directory {
-	uint32_t directory_version;
-	uint32_t img_info_offset;
-	uint32_t num_images;
-	uint32_t correct_boot;
-	uint32_t img_info_size;
-	uint32_t reserved;
-	struct ts_fwu_image_info_entry img_info_entry[];
-};
-
-/**
- * Message parameters
- */
-
-struct __attribute__((__packed__)) ts_fwu_discover_out {
-	uint8_t version_major;
-	uint8_t version_minor;
-	uint16_t num_func;
-	uint8_t function_presence[];
-};
-
-struct __attribute__((__packed__)) ts_fwu_open_in {
-	uint8_t image_type_uuid[OSF_UUID_OCTET_LEN];
-};
-
-struct __attribute__((__packed__)) ts_fwu_open_out {
-	uint32_t handle;
-};
-
-struct __attribute__((__packed__)) ts_fwu_write_stream_in {
-	uint32_t handle;
-	uint32_t data_len;
-	uint8_t payload[];
-};
-
-struct __attribute__((__packed__)) ts_fwu_read_stream_in {
-	uint32_t handle;
-};
-
-struct __attribute__((__packed__)) ts_fwu_read_stream_out {
-	uint32_t read_bytes;
-	uint32_t total_bytes;
-	uint8_t payload[];
-};
-
-struct __attribute__((__packed__)) ts_fwu_commit_in {
-	uint32_t handle;
-	uint32_t acceptance_req;
-	uint32_t max_atomic_len;
-};
-
-struct __attribute__((__packed__)) ts_fwu_commit_out {
-	uint32_t progress;
-	uint32_t total_work;
-};
-
-struct __attribute__((__packed__)) ts_fwu_accept_image_in {
-	uint32_t reserved;
-	uint8_t image_type_uuid[OSF_UUID_OCTET_LEN];
-};
-
-#endif /* FWU_PROTO_H */
diff --git a/protocols/service/fwu/packed-c/opcodes.h b/protocols/service/fwu/packed-c/opcodes.h
deleted file mode 100644
index 1905a65..0000000
--- a/protocols/service/fwu/packed-c/opcodes.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#ifndef FWU_PROTO_OPCODES_H
-#define FWU_PROTO_OPCODES_H
-
-/**
- * Service-level opcodes
- */
-#define TS_FWU_OPCODE_BASE	      (0x10)
-#define TS_FWU_OPCODE_BEGIN_STAGING   (TS_FWU_OPCODE_BASE + 0)
-#define TS_FWU_OPCODE_END_STAGING     (TS_FWU_OPCODE_BASE + 1)
-#define TS_FWU_OPCODE_CANCEL_STAGING  (TS_FWU_OPCODE_BASE + 2)
-#define TS_FWU_OPCODE_OPEN	      (TS_FWU_OPCODE_BASE + 3)
-#define TS_FWU_OPCODE_WRITE_STREAM    (TS_FWU_OPCODE_BASE + 4)
-#define TS_FWU_OPCODE_READ_STREAM     (TS_FWU_OPCODE_BASE + 5)
-#define TS_FWU_OPCODE_COMMIT	      (TS_FWU_OPCODE_BASE + 6)
-#define TS_FWU_OPCODE_ACCEPT_IMAGE    (TS_FWU_OPCODE_BASE + 7)
-#define TS_FWU_OPCODE_SELECT_PREVIOUS (TS_FWU_OPCODE_BASE + 8)
-
-#endif /* FWU_PROTO_OPCODES_H */
diff --git a/protocols/service/fwu/packed-c/status.h b/protocols/service/fwu/status.h
similarity index 100%
rename from protocols/service/fwu/packed-c/status.h
rename to protocols/service/fwu/status.h
diff --git a/tools/b-test/test_data.yaml b/tools/b-test/test_data.yaml
index 9167312..029dc1d 100644
--- a/tools/b-test/test_data.yaml
+++ b/tools/b-test/test_data.yaml
@@ -40,6 +40,12 @@
       os_id : "GNU/Linux"
       params:
             - "-GUnix Makefiles"
+    - name: "component-test-coverage-linux-pc"
+      src: "$TS_ROOT/deployments/component-test/linux-pc"
+      os_id : "GNU/Linux"
+      params:
+            - "-GUnix Makefiles"
+            - "-DCOVERAGE=1"
     - name: "crypto-default-opteesp"
       src: "$TS_ROOT/deployments/crypto/config/default-opteesp"
       params:
@@ -85,11 +91,33 @@
       src: "$TS_ROOT/deployments/internal-trusted-storage/config/shared-flash-opteesp"
       params:
             - "-GUnix Makefiles"
+    - name: "libpsats-arm-linux"
+      src: "$TS_ROOT/deployments/libpsats/arm-linux"
+      os_id : "GNU/Linux"
+      params:
+            - "-GUnix Makefiles"
+    - name: "libpsats-linux-pc"
+      src: "$TS_ROOT/deployments/libpsats/linux-pc"
+      os_id : "GNU/Linux"
+      params:
+            - "-GUnix Makefiles"
+    - name: "libpsats-coverage-linux-pc"
+      src: "$TS_ROOT/deployments/libpsats/linux-pc"
+      os_id : "GNU/Linux"
+      params:
+            - "-GUnix Makefiles"
+            - "-DCOVERAGE=1"
     - name: "libsp-linux-pc"
       src: "$TS_ROOT/deployments/libsp/linux-pc"
       os_id : "GNU/Linux"
       params:
             - "-GUnix Makefiles"
+    - name: "libsp-coverage-linux-pc"
+      src: "$TS_ROOT/deployments/libsp/linux-pc"
+      os_id : "GNU/Linux"
+      params:
+            - "-GUnix Makefiles"
+            - "-DCOVERAGE=1"
     - name: "libsp-opteesp"
       src: "$TS_ROOT/deployments/libsp/opteesp"
       params:
@@ -104,10 +132,12 @@
       os_id : "GNU/Linux"
       params:
             - "-GUnix Makefiles"
-    - name: "newlib-opteesp"
-      src: "$TS_ROOT/deployments/newlib/opteesp"
+    - name: "libts-coverage-linux-pc"
+      src: "$TS_ROOT/deployments/libts/linux-pc"
+      os_id : "GNU/Linux"
       params:
             - "-GUnix Makefiles"
+            - "-DCOVERAGE=1"
     - name: "platform-inspect-arm-linux"
       src: "$TS_ROOT/deployments/platform-inspect/arm-linux"
       os_id : "GNU/Linux"
@@ -187,6 +217,12 @@
       os_id : "GNU/Linux"
       params:
             - "-GUnix Makefiles"
+    - name: "smm-gateway-coverage-linux-pc"
+      src: "$TS_ROOT/deployments/smm-gateway/config/linux-pc"
+      os_id : "GNU/Linux"
+      params:
+            - "-GUnix Makefiles"
+            - "-DCOVERAGE=1"
     - name: "spm-test1-opteesp"
       src: "$TS_ROOT/deployments/spm-test1/opteesp"
       params:
@@ -233,6 +269,12 @@
       os_id : "GNU/Linux"
       params:
             - "-GUnix Makefiles"
+    - name: "ts-service-test-coverage-linux-pc"
+      src: "$TS_ROOT/deployments/ts-service-test/linux-pc"
+      os_id : "GNU/Linux"
+      params:
+            - "-GUnix Makefiles"
+            - "-DCOVERAGE=1"
     - name: "uefi-test-arm-linux"
       src: "$TS_ROOT/deployments/uefi-test/arm-linux"
       os_id : "GNU/Linux"
@@ -243,3 +285,9 @@
       os_id : "GNU/Linux"
       params:
             - "-GUnix Makefiles"
+    - name: "uefi-test-coverage-linux-pc"
+      src: "$TS_ROOT/deployments/uefi-test/linux-pc"
+      os_id : "GNU/Linux"
+      params:
+            - "-GUnix Makefiles"
+            - "-DCOVERAGE=1"
diff --git a/tools/bash/uefi_authenticated_variables/generate_auth_headers.sh b/tools/bash/uefi_authenticated_variables/generate_auth_headers.sh
index 47442ac..6ee4de5 100755
--- a/tools/bash/uefi_authenticated_variables/generate_auth_headers.sh
+++ b/tools/bash/uefi_authenticated_variables/generate_auth_headers.sh
@@ -25,7 +25,10 @@
 # PK2  --> PK2 : delete
 # PK1 --> KEK : delete
 # KEK --> db1
-# db1 --> var
+# var --> var : append
+# var --> var : append_old
+# var --> var : delete
+# var --> var : delete_old
 # @enduml
 
 # Check environment
@@ -62,14 +65,16 @@
 generate_key_cert "VAR"
 
 # Create data file for the custom variable
-cat <<EOF > var_data.txt
+cat <<EOF > var_data_part01.txt
 The term 'trusted service' is used as a general name for a class of application that runs in an isolated
 processing environment. Other applications rely on trusted services to perform security related operations in
 a way that avoids exposing secret data beyond the isolation boundary of the environment. The word 'trusted'
 does not imply anything inherently trustworthy about a service application but rather that other applications
 put trust in the service. Meeting those trust obligations relies on a range of hardware and firmware
 implemented security measures.
+EOF
 
+cat <<EOF > var_data_part02.txt
 The Arm Application-profile (A-profile) architecture, in combination with standard firmware, provides a range
 of isolated processing environments that offer hardware-backed protection against various classes of attack.
 Because of their strong security properties, these environments are suitable for running applications that have
@@ -90,6 +95,8 @@
 Functional APIs. UEFI SMM services are provided by the SMM Gateway.
 EOF
 
+cat var_data_part01.txt var_data_part02.txt > var_data.txt
+
 # Generate EFI signature list from the certificates for each keystore variable and an empty esl for delete requests
 cert-to-efi-sig-list PK1.crt PK1.esl
 cert-to-efi-sig-list PK2.crt PK2.esl
@@ -102,32 +109,39 @@
 # Add another signature list before the correct KEK list to test if multiple lists are supported
 cat PK3.esl KEK.esl > KEK_concatenated.esl
 
-sign-efi-sig-list -c PK1.crt -k PK1.key PK  PK1.esl               PK1.auth
-sign-efi-sig-list -c PK1.crt -k PK1.key PK  PK2.esl               PK2.auth
-sign-efi-sig-list -c PK3.crt -k PK3.key PK  PK3.esl               PK3.auth
-sign-efi-sig-list -c PK1.crt -k PK1.key PK  NULL.esl              PK1_delete.auth
-sign-efi-sig-list -c PK2.crt -k PK2.key PK  NULL.esl              PK2_delete.auth
-sign-efi-sig-list -c PK1.crt -k PK1.key KEK KEK_concatenated.esl  KEK.auth
-sign-efi-sig-list -c PK1.crt -k PK1.key KEK NULL.esl              KEK_delete.auth
-sign-efi-sig-list -c KEK.crt -k KEK.key db  DB1.esl               DB1.auth
-sign-efi-sig-list -c PK1.crt -k PK1.key db  DB2.esl               DB2.auth
+sign-efi-sig-list -c PK1.crt -k PK1.key PK  PK1.esl               PK1.auth        ; sleep 1
+sign-efi-sig-list -c PK1.crt -k PK1.key PK  NULL.esl              PK1_delete.auth ; sleep 1
+sign-efi-sig-list -c PK1.crt -k PK1.key PK  PK2.esl               PK2.auth        ; sleep 1
+sign-efi-sig-list -c PK2.crt -k PK2.key PK  NULL.esl              PK2_delete.auth ; sleep 1
+sign-efi-sig-list -c PK3.crt -k PK3.key PK  PK3.esl               PK3.auth        ; sleep 1
+sign-efi-sig-list -c PK1.crt -k PK1.key KEK KEK_concatenated.esl  KEK.auth        ; sleep 1
+sign-efi-sig-list -c PK1.crt -k PK1.key KEK NULL.esl              KEK_delete.auth ; sleep 1
+sign-efi-sig-list -c PK1.crt -k PK1.key db  DB2.esl               DB2.auth        ; sleep 1
+sign-efi-sig-list -c KEK.crt -k KEK.key db  DB1.esl               DB1.auth        ; sleep 1
+
 # GUID: Must be syncronized with m_common_guid in the tests
-sign-efi-sig-list -c DB1.crt -k DB1.key -g '01234567-89AB-CDEF-0123-456789ABCDEF' var var_data.txt VAR.auth
-sign-efi-sig-list -c DB1.crt -k DB1.key -g '01234567-89AB-CDEF-0123-456789ABCDEF' var /dev/null VAR_delete.auth
+sign-efi-sig-list -c VAR.crt -k VAR.key -g '01234567-89AB-CDEF-0123-456789ABCDEF' -t 0 -a var var_data_part02.txt var_append_old.auth
+sign-efi-sig-list -c VAR.crt -k VAR.key -g '01234567-89AB-CDEF-0123-456789ABCDEF' -t 0 var /dev/null var_delete_old.auth          ; sleep 1
+sign-efi-sig-list -c VAR.crt -k VAR.key -g '01234567-89AB-CDEF-0123-456789ABCDEF' var var_data_part01.txt var.auth                ; sleep 1
+sign-efi-sig-list -c VAR.crt -k VAR.key -g '01234567-89AB-CDEF-0123-456789ABCDEF' -a var var_data_part02.txt var_append.auth      ; sleep 1
+sign-efi-sig-list -c VAR.crt -k VAR.key -g '01234567-89AB-CDEF-0123-456789ABCDEF' var /dev/null var_delete.auth                   ; sleep 1
 
 # Generate C headers from the authentication headers for the tests
-xxd -i PK1.auth        > ../${HEADER_FOLDER}/PK1.h
-xxd -i PK2.auth        > ../${HEADER_FOLDER}/PK2.h
-xxd -i PK3.auth        > ../${HEADER_FOLDER}/PK3.h
-xxd -i PK1_delete.auth > ../${HEADER_FOLDER}/PK1_delete.h
-xxd -i PK2_delete.auth > ../${HEADER_FOLDER}/PK2_delete.h
-xxd -i KEK.auth        > ../${HEADER_FOLDER}/KEK.h
-xxd -i KEK_delete.auth > ../${HEADER_FOLDER}/KEK_delete.h
-xxd -i DB1.auth        > ../${HEADER_FOLDER}/db1.h
-xxd -i DB2.auth        > ../${HEADER_FOLDER}/db2.h
-xxd -i VAR.auth        > ../${HEADER_FOLDER}/var.h
-xxd -i VAR_delete.auth > ../${HEADER_FOLDER}/var_delete.h
-xxd -i var_data.txt    > ../${HEADER_FOLDER}/var_data.h
+xxd -i PK1.auth            > ../${HEADER_FOLDER}/PK1.h
+xxd -i PK2.auth            > ../${HEADER_FOLDER}/PK2.h
+xxd -i PK3.auth            > ../${HEADER_FOLDER}/PK3.h
+xxd -i PK1_delete.auth     > ../${HEADER_FOLDER}/PK1_delete.h
+xxd -i PK2_delete.auth     > ../${HEADER_FOLDER}/PK2_delete.h
+xxd -i KEK.auth            > ../${HEADER_FOLDER}/KEK.h
+xxd -i KEK_delete.auth     > ../${HEADER_FOLDER}/KEK_delete.h
+xxd -i DB2.auth            > ../${HEADER_FOLDER}/db2.h
+xxd -i DB1.auth            > ../${HEADER_FOLDER}/db1.h
+xxd -i var_append_old.auth > ../${HEADER_FOLDER}/var_append_old.h
+xxd -i var_delete_old.auth > ../${HEADER_FOLDER}/var_delete_old.h
+xxd -i var.auth            > ../${HEADER_FOLDER}/var.h
+xxd -i var_append.auth     > ../${HEADER_FOLDER}/var_append.h
+xxd -i var_delete.auth     > ../${HEADER_FOLDER}/var_delete.h
+xxd -i var_data.txt        > ../${HEADER_FOLDER}/var_data.h
 
 popd
 
diff --git a/tools/cmake/common/ExportLibrary.cmake b/tools/cmake/common/ExportLibrary.cmake
index c171c5b..22ed313 100644
--- a/tools/cmake/common/ExportLibrary.cmake
+++ b/tools/cmake/common/ExportLibrary.cmake
@@ -44,6 +44,7 @@
 
 
 	string(TOLOWER "${MY_PARAMS_LIB_NAME}" LC_LIB_NAME)
+	set(_version_file_name "${LC_LIB_NAME}ConfigVersion.cmake")
 
 	# Set default install location if none specified
 	if (CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
@@ -76,7 +77,7 @@
 	include(CMakePackageConfigHelpers)
 	get_target_property(_ver ${MY_PARAMS_TARGET} VERSION)
 	write_basic_package_version_file(
-		"${CMAKE_CURRENT_BINARY_DIR}/${LC_LIB_NAME}ConfigVersion.cmake"
+		"${CMAKE_CURRENT_BINARY_DIR}/${_version_file_name}"
 		VERSION "${_ver}"
 		COMPATIBILITY SameMajorVersion
 	)
@@ -87,6 +88,7 @@
 
 	get_filename_component(_configured_pkgcfg_name "${MY_PARAMS_PKG_CONFIG_FILE}" NAME_WLE)
 	set(_configured_pkgcfg_name "${CMAKE_CURRENT_BINARY_DIR}/${_configured_pkgcfg_name}")
+
 	configure_package_config_file(
 			"${MY_PARAMS_PKG_CONFIG_FILE}"
 			"${_configured_pkgcfg_name}"
@@ -108,7 +110,7 @@
 	install(
 		FILES
 			"${_configured_pkgcfg_name}"
-			"${CMAKE_CURRENT_BINARY_DIR}/${LC_LIB_NAME}ConfigVersion.cmake"
+			"${CMAKE_CURRENT_BINARY_DIR}/${_version_file_name}"
 		DESTINATION
 			${ConfigPackageLocation}
 		COMPONENT
diff --git a/tools/cmake/common/ExportSp.cmake b/tools/cmake/common/ExportSp.cmake
index ceb7700..c9347c4 100644
--- a/tools/cmake/common/ExportSp.cmake
+++ b/tools/cmake/common/ExportSp.cmake
@@ -85,20 +85,6 @@
 	set(SP_UUID_LE " 0x${_uuid_le}" PARENT_SCOPE)
 	set(EXPORT_SP_UUID_DT " 0x${_uuid_le}")
 
-	# As the .dtsi is meant to be included in .dts file, it shouldn't contain a separate
-	# /dts-v1/ tag and its node should be unique, i.e. the SP name.
-	set(DTS_TAG "")
-	set(DTS_NODE "${EXPORT_SP_NAME}")
-	configure_file(${EXPORT_DTS_IN} ${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_SP_BIN_UUID_CANON}_before_preprocessing.dtsi @ONLY NEWLINE_STYLE UNIX)
-
-	compiler_preprocess_file(
-		SRC ${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_SP_BIN_UUID_CANON}_before_preprocessing.dtsi
-		DST ${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_SP_BIN_UUID_CANON}.dtsi
-		TARGET ${EXPORT_SP_NAME}
-	)
-
-	install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${EXPORT_SP_BIN_UUID_CANON}.dtsi DESTINATION ${TS_ENV}/manifest)
-
 	# The .dts file is a standalone structure, thus it should have the /dts-v1/ tag and it
 	# starts with the root node.
 	set(DTS_TAG "/dts-v1/;")
diff --git a/tools/cmake/common/LazyFetch.cmake b/tools/cmake/common/LazyFetch.cmake
index 0c00bce..577bd45 100644
--- a/tools/cmake/common/LazyFetch.cmake
+++ b/tools/cmake/common/LazyFetch.cmake
@@ -140,7 +140,7 @@
 	endif()
 
 	if (DEFINED ${UC_DEP_NAME}_VERBOSE_BUILD OR DEFINED ENV{${UC_DEP_NAME}_VERBOSE_BUILD})
-		set(_CMAKE_VERBOSE_CFG_FLAG "--verbose")
+		set(_CMAKE_VERBOSE_BLD_FLAG "--verbose")
 	endif()
 
 	if (BUILD_INSTALL_DIR)
diff --git a/tools/cmake/compiler/GCC.cmake b/tools/cmake/compiler/GCC.cmake
index 79f9158..e230e9d 100644
--- a/tools/cmake/compiler/GCC.cmake
+++ b/tools/cmake/compiler/GCC.cmake
@@ -1,5 +1,5 @@
 #-------------------------------------------------------------------------------
-# Copyright (c) 2019-2023, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2019-2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -386,14 +386,6 @@
 		message(FATAL_ERROR "Mandatory parameter TARGET is missing!")
 	endif()
 
-	# Set INTERFACE options for imported targets and PUBLIC otherwise.
-	get_property(_is_imported_target TARGET ${MY_TARGET} PROPERTY IMPORTED SET)
-	if (_is_imported_target)
-		set(_option_type INTERFACE)
-	else()
-		set(_option_type PUBLIC)
-	endif()
-
 	### Get the location of libgcc.a
 	# Copy values from environment if present. Note: if the value is already in the CACHE, this set will have no effect.
 	if(DEFINED ENV{LIBGCC_PATH})
@@ -463,8 +455,8 @@
 	endif()
 
 	# Configure the target for freestanding mode.
-	target_compile_options(${MY_TARGET} ${_option_type} "-nostdinc")
-	target_include_directories(${MY_TARGET} SYSTEM ${_option_type} ${LIBGCC_INCLUDE_DIRS})
-	target_link_options(${MY_TARGET} ${_option_type} "-nostdlib" "-nostartfiles")
-	target_link_libraries(${MY_TARGET} ${_option_type} "${LIBGCC_PATH}")
+	target_compile_options(${MY_TARGET} PUBLIC -nostdinc -ffreestanding -fno-builtin)
+	target_include_directories(${MY_TARGET} SYSTEM PUBLIC ${LIBGCC_INCLUDE_DIRS})
+	target_link_options(${MY_TARGET} PUBLIC "-nostdlib" "-nostartfiles")
+	target_link_libraries(${MY_TARGET} PUBLIC "${LIBGCC_PATH}")
 endfunction()
diff --git a/tools/python/elf_segments_to_manifest.py b/tools/python/elf_segments_to_manifest.py
index 5528164..378c318 100644
--- a/tools/python/elf_segments_to_manifest.py
+++ b/tools/python/elf_segments_to_manifest.py
@@ -1,7 +1,7 @@
 #!/usr/bin/env python3
 # SPDX-License-Identifier: BSD-3-Clause
 #
-# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2024, Arm Limited. All rights reserved.
 
 """
 This module's goal is to take an ELF file as an input and extract the memory
@@ -12,9 +12,11 @@
 
 from enum import IntFlag
 from math import ceil
+from elftools import __version__ as module_version
 from elftools.elf.elffile import ELFFile
 from elftools.elf.constants import P_FLAGS
 
+assert module_version == "0.31"
 
 class ElfSegmentsToManifest:
     """
@@ -23,6 +25,33 @@
     """
     PAGE_SIZE = 4096
 
+    class GnuNotePropertySection:
+        """ Provides an API to process GNU note property section. """
+
+        GNU_PROPERTY_AARCH64_FEATURE_1_BTI = 1
+
+        def __init__(self, section):
+            self.section = section
+
+        def is_bti_enabled(self):
+            """ Returns whether any of the notes has a BTI enable property """
+
+            def is_bti_property(prop):
+                return prop['pr_type'] == "GNU_PROPERTY_AARCH64_FEATURE_1_AND" and \
+                    prop['pr_data'] & self.GNU_PROPERTY_AARCH64_FEATURE_1_BTI
+
+            def has_bti_property(note):
+                return note["n_name"] == 'GNU' and note["n_type"] == "NT_GNU_PROPERTY_TYPE_0" and \
+                    any(is_bti_property(p) for p in note["n_desc"])
+
+            return any(has_bti_property(n) for n in self.section.iter_notes())
+
+        @staticmethod
+        def is_matching_section(section):
+            """ Checks if the section is a GNU note property section """
+            return section.name == '.note.gnu.property'
+
+
     class Region:
         """ Describes a memory region and its attributes. """
 
@@ -31,6 +60,8 @@
             R = 0x01
             W = 0x02
             X = 0x04
+            S = 0x08
+            GP = 0x10
 
             def get_attr(self):
                 """ Queries the value of the attributes in manifest format. """
@@ -82,6 +113,11 @@
             self.end_address = region.end_address
             self.sections += region.sections
 
+        def set_bti_if_executable(self):
+            """ Sets GP flag if the region is executable. """
+            if self.attributes & self.ManifestMemAttr.X:
+                self.attributes |= self.ManifestMemAttr.GP
+
         def write_manifest(self, load_base_addr, manifest_file):
             """
             Writes the region into the manifest file. The address is adjusted by load_base_address.
@@ -131,7 +167,16 @@
                 return segment.header.p_align == ElfSegmentsToManifest.PAGE_SIZE
             assert is_aligned(segment), "Segments must be 4k aligned, check LD script"
             self.segment = segment
-            self.sections = [s for s in sections if self.segment.section_in_segment(s)]
+            self.sections = []
+            self.gnu_note = None
+
+            for section in sections:
+                if self.segment.section_in_segment(section):
+                    if ElfSegmentsToManifest.GnuNotePropertySection.is_matching_section(section):
+                        self.gnu_note = ElfSegmentsToManifest.GnuNotePropertySection(section)
+                    else:
+                        self.sections.append(section)
+
             self.regions = []
             self.merge_sections_to_regions()
 
@@ -150,6 +195,11 @@
                     self.regions.append(region)
                     current_region = region
 
+            # Set GP only for the executable regions if BTI is enabled in the segment
+            if self.gnu_note and self.gnu_note.is_bti_enabled():
+                for region in self.regions:
+                    region.set_bti_if_executable()
+
         def write_manifest(self, load_base_addr, manifest_file):
             """ Writes the regions into the manifest file. """
             for region in self.regions:
diff --git a/tools/python/requirements.txt b/tools/python/requirements.txt
index 81bf605..208c74f 100644
--- a/tools/python/requirements.txt
+++ b/tools/python/requirements.txt
@@ -1,7 +1,7 @@
 #
-# Copyright (c) 2022, Arm Limited and Contributors. All rights reserved.
+# Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
-pyelftools==0.28
+pyelftools==0.31
diff --git a/version.txt b/version.txt
index afaf360..1cc5f65 100644
--- a/version.txt
+++ b/version.txt
@@ -1 +1 @@
-1.0.0
\ No newline at end of file
+1.1.0
\ No newline at end of file