Create encrypted, partitioned block store factory

Create a factory, which assembles a ram block store device with
encyption and partition layers on top of it.

Change-Id: Iac97962f17472eee0d3a01a3766bb51560772555
Signed-off-by: Gabor Toth <gabor.toth2@arm.com>
diff --git a/components/service/block_storage/factory/ref_encrypt_ram/block_store_factory.c b/components/service/block_storage/factory/ref_encrypt_ram/block_store_factory.c
new file mode 100644
index 0000000..e0e49b9
--- /dev/null
+++ b/components/service/block_storage/factory/ref_encrypt_ram/block_store_factory.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "block_store_factory.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "service/block_storage/block_store/device/ram/ram_block_store.h"
+#include "service/block_storage/block_store/encrypted/encrypted_block_store.h"
+#include "service/block_storage/block_store/partitioned/partitioned_block_store.h"
+#include "service/block_storage/config/ref/ref_partition_configurator.h"
+
+struct block_store_assembly {
+	struct partitioned_block_store partitioned_block_store;
+	struct encrypted_block_store encrypted_block_store;
+	struct ram_block_store ram_block_store;
+};
+
+struct block_store *ref_encrypt_ram_block_store_factory_create(void)
+{
+	struct block_store *product = NULL;
+	struct uuid_octets back_store_guid;
+	struct block_store *back_store = NULL;
+	struct block_store_assembly *assembly =
+		(struct block_store_assembly *)calloc(1, sizeof(struct block_store_assembly));
+
+	if (!assembly)
+		return NULL;
+
+	memset(&back_store_guid, 0, sizeof(back_store_guid));
+
+	/* Initialise a ram_block_store to provide underlying storage */
+	back_store = ram_block_store_init(&assembly->ram_block_store,
+								&back_store_guid,
+								REF_PARTITION_BACK_STORE_SIZE,
+								REF_PARTITION_BLOCK_SIZE);
+
+	/* Stack an encrypted block store over the partitioned one */
+	product = encrypted_block_store_init(&assembly->encrypted_block_store, 0,
+						&back_store_guid, back_store);
+
+	if (!product) {
+		ram_block_store_deinit(&assembly->ram_block_store);
+		free(assembly);
+		return NULL;
+	}
+
+	/* Stack a partitioned_block_store over the back store */
+	product = partitioned_block_store_init(&assembly->partitioned_block_store, 0,
+						&back_store_guid, product, NULL);
+
+	if (!product) {
+		encrypted_block_store_deinit(&assembly->encrypted_block_store);
+		ram_block_store_deinit(&assembly->ram_block_store);
+		free(assembly);
+		return NULL;
+	}
+
+	/* Use the reference partition configuration */
+	ref_partition_configure(&assembly->partitioned_block_store);
+
+	return product;
+}
+
+void ref_encrypt_ram_block_store_factory_destroy(struct block_store *block_store)
+{
+	struct block_store_assembly *assembly = NULL;
+
+	if (!block_store)
+		return;
+
+	assembly = (struct block_store_assembly *)((uint8_t *)block_store);
+
+	partitioned_block_store_deinit(&assembly->partitioned_block_store);
+	encrypted_block_store_deinit(&assembly->encrypted_block_store);
+	ram_block_store_deinit(&assembly->ram_block_store);
+
+	free(assembly);
+}
diff --git a/components/service/block_storage/factory/ref_encrypt_ram/block_store_factory.h b/components/service/block_storage/factory/ref_encrypt_ram/block_store_factory.h
new file mode 100644
index 0000000..fdb38df
--- /dev/null
+++ b/components/service/block_storage/factory/ref_encrypt_ram/block_store_factory.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef REF_ENCRYPT_RAM_BLOCK_STORE_FACTORY_H
+#define REF_ENCRYPT_RAM_BLOCK_STORE_FACTORY_H
+
+#include "service/block_storage/block_store/block_store.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * A block store factory that constructs an encrypted, partitioned block store
+ * with a ram back store. The reference partition configuration is used to
+ * provide a set of storage partitions that match the expectations of
+ * test cases. This factory should only be used for test deployments.
+ */
+
+/**
+ * \brief Factory method to create a block_store
+ *
+ * \return A pointer to the constructed block_store (NULL on failure)
+ */
+struct block_store *ref_encrypt_ram_block_store_factory_create(void);
+
+/**
+ * \brief Destroys a block_store created with block_store_factory_create
+ *
+ * \param[in] block_store    The block store to destroy
+ */
+void ref_encrypt_ram_block_store_factory_destroy(struct block_store *block_store);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* REF_ENCRYPT_RAM_BLOCK_STORE_FACTORY_H */
diff --git a/components/service/block_storage/factory/ref_encrypt_ram/component.cmake b/components/service/block_storage/factory/ref_encrypt_ram/component.cmake
new file mode 100644
index 0000000..eea94ec
--- /dev/null
+++ b/components/service/block_storage/factory/ref_encrypt_ram/component.cmake
@@ -0,0 +1,20 @@
+#-------------------------------------------------------------------------------
+# 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()
+
+target_sources(${TGT} PRIVATE
+	"${CMAKE_CURRENT_LIST_DIR}/block_store_factory.c"
+	)
+
+# If none already defined, make this the default factory for the deployment
+if (NOT DEFINED TS_BLOCK_STORE_FACTORY)
+	set(TS_BLOCK_STORE_FACTORY "ref_encrypt_ram_block_store_factory")
+	target_compile_definitions(${TGT} PRIVATE
+		CONCRETE_BLOCK_STORE_FACTORY=${TS_BLOCK_STORE_FACTORY})
+endif()
\ No newline at end of file