SST: Implement SST flash on top of CMSIS flash drv
This patch implements SST flash interface on top
of CMSIS flash driver.
It also adds a missing include in sst_utils.h.
Change-Id: I70610584a124d72c2ec6bd911618e0c60e3c7463
Signed-off-by: Marc Moreno <marc.morenoberengue@arm.com>
diff --git a/CommonConfig.cmake b/CommonConfig.cmake
index 8241045..979c797 100755
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -158,7 +158,9 @@
set(MBEDTLS_C_FLAGS "-D__ARM_FEATURE_CMSE=3 -D__thumb2__ ${COMMON_COMPILE_FLAGS_STR} -DMBEDTLS_CONFIG_FILE=\\\\\\\"mbedtls_config.h\\\\\\\" -I${CMAKE_CURRENT_LIST_DIR}/platform/ext/common")
set (SST_ENCRYPTION ON)
-set (SST_RAM_FS ON)
+if (NOT DEFINED SST_RAM_FS)
+ set (SST_RAM_FS OFF)
+endif()
set (SST_VALIDATE_METADATA_FROM_FLASH ON)
set (ENABLE_SECURE_STORAGE ON)
set (MBEDTLS_DEBUG ON)
diff --git a/platform/ext/Mps2AN519.cmake b/platform/ext/Mps2AN519.cmake
index 95a21aa..dfa6c21 100755
--- a/platform/ext/Mps2AN519.cmake
+++ b/platform/ext/Mps2AN519.cmake
@@ -112,5 +112,12 @@
message(FATAL_ERROR "Configuration variable BUILD_FLASH (true|false) is undefined!")
elseif(BUILD_FLASH)
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an519/cmsis_drivers/Driver_Flash.c")
+ # There is no real flash memory for code on MPS2 board. Instead a code SRAM is
+ # used for code storage: ZBT SSRAM1. The Driver_Flash driver just emulates a flash
+ # interface and behaviour on top of the SRAM memory.
+ # As the SST area is going to be in RAM, it is required to set SST_RAM_FS to be sure the
+ # SST service knows that when it starts the SST area does not contain any valid block and
+ # it needs to create an empty one.
+ set(SST_RAM_FS True)
embedded_include_directories(PATH "${PLATFORM_DIR}/target/mps2/an519/cmsis_drivers" ABSOLUTE)
endif()
diff --git a/platform/ext/Mps2AN521.cmake b/platform/ext/Mps2AN521.cmake
index 8dc53a8..a740066 100755
--- a/platform/ext/Mps2AN521.cmake
+++ b/platform/ext/Mps2AN521.cmake
@@ -129,5 +129,12 @@
message(FATAL_ERROR "Configuration variable BUILD_FLASH (true|false) is undefined!")
elseif(BUILD_FLASH)
list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an521/cmsis_drivers/Driver_Flash.c")
+ # There is no real flash memory for code on MPS2 board. Instead a code SRAM is
+ # used for code storage: ZBT SSRAM1. The Driver_Flash driver just emulates a flash
+ # interface and behaviour on top of the SRAM memory.
+ # As the SST area is going to be in RAM, it is required to set SST_RAM_FS to be sure the
+ # SST service knows that when it starts the SST area does not contain any valid block and
+ # it needs to create an empty one.
+ set(SST_RAM_FS True)
embedded_include_directories(PATH "${PLATFORM_DIR}/target/mps2/an521/cmsis_drivers" ABSOLUTE)
endif()
diff --git a/platform/ext/readme.md b/platform/ext/readme.md
index 7b94540..8cd2bce 100644
--- a/platform/ext/readme.md
+++ b/platform/ext/readme.md
@@ -16,6 +16,7 @@
CMSIS_5 project.
### common
+
This folder contains stdout redirection to UART, a temporary memory mapped
flash implementation for the bootloader and mbedtls_config.h for all
the targets.
@@ -26,8 +27,82 @@
that TF-M project expects a target to provide.
### target
+
This folder contains the files for individual target.
+#### Flash layout header file
+
+Target must provide a header file, called flash_layout.h, which defines the
+information explained in the follow subsections. The defines must be named
+as they are in the subsections.
+
+##### BL2 bootloader
+
+The BL2 bootloader requires the following definitions:
+
+ - `FLASH_BASE_ADDRESS`
+ Defines the first valid address in the flash.
+ - `FLASH_AREA_BL2_OFFSET`
+ Defines the offset from the flash base address
+ where the BL2 - MCUBOOT area starts.
+ - `FLASH_AREA_BL2_SIZE`
+ Defines the size of the BL2 area.
+ - `FLASH_AREA_IMAGE_0_OFFSET`
+ Defines the offset from the flash base address
+ where the image 0 area starts, which hosts the
+ active firmware image.
+ - `FLASH_AREA_IMAGE_0_SIZE`
+ Defines the size of the image 0 area.
+ - `FLASH_AREA_IMAGE_1_OFFSET`
+ Defines the offset from the flash base address
+ where the image 1 area starts, which is a placeholder
+ for new firmware images.
+ - `FLASH_AREA_IMAGE_1_SIZE`
+ Defines the size of the image 1 area.
+ - `FLASH_AREA_IMAGE_SCRATCH_OFFSET`
+ Defines the offset from the flash base address
+ where the scratch area starts, which is used during
+ image swapping.
+ - `FLASH_AREA_IMAGE_SCRATCH_SIZE`
+ Defines the size of the scratch area. The minimal size
+ must be as the biggest sector size in the flash.
+ - `FLASH_DEV_NAME`
+ Specifies the flash device used by BL2 and SST.
+
+##### Assemble tool
+
+The assemble.py tools is used to concatenate secure and non-secure
+binary to a single binary blob. It requires the following definitions:
+
+ - `SECURE_IMAGE_OFFSET`
+ Defines the offset from the single binary blob base address,
+ where the secure image starts.
+ - `SECURE_IMAGE_MAX_SIZE`
+ Defines the maximum size of the secure image area.
+ - `NON_SECURE_IMAGE_OFFSET`
+ Defines the offset from the single binary blob base address,
+ where the non-secure image starts.
+ - `NON_SECURE_IMAGE_MAX_SIZE`
+ Defines the maximum size of the non-secure image area.
+
+##### Secure Storage (SST) Service definitions
+
+The SST service requires the following definitions:
+
+ - `SST_FLASH_AREA_ADDR`
+ Defines the flash area address where the secure
+ store area starts.
+ - `SST_SECTOR_SIZE`
+ Defines the size of the flash sectors.
+ - `SST_NBR_OF_SECTORS`
+ Defines the number of sectors avilable for
+ the secure area.
+ - `FLASH_DEV_NAME`
+ Specifies the flash device used by BL2 and SST.
+ - `SST_FLASH_PROGRAM_UNIT`
+ Defines the smallest flash programmable unit in bytes.
+
+**Note**: The sectors must be consecutive.
--------------
diff --git a/platform/ext/target/mps2/an519/partition/flash_layout.h b/platform/ext/target/mps2/an519/partition/flash_layout.h
index 91ebf73..a0881d1 100644
--- a/platform/ext/target/mps2/an519/partition/flash_layout.h
+++ b/platform/ext/target/mps2/an519/partition/flash_layout.h
@@ -27,7 +27,8 @@
* 0x0018_0000 Secure image secondary
* 0x0020_0000 Non-secure image secondary
* 0x0028_0000 Scratch area(1 MB)
- * 0x0038_0000 Unused(0.5 MB)
+ * 0x0038_0000 Secure Storage Area (0.02 MB)
+ * 0x0038_5000 Unused(0.482 MB)
*
* Flash layout on MPS2 AN519, if BL2 not defined:
* 0x0000_0000 Secure image
@@ -71,6 +72,9 @@
#define FLASH_AREA_IMAGE_SCRATCH_OFFSET (0x280000)
#define FLASH_AREA_IMAGE_SCRATCH_SIZE (2 * FLASH_PARTITION_SIZE)
+#define FLASH_SST_AREA_OFFSET (0x380000)
+#define FLASH_SST_AREA_SIZE (0x5000) /* 20 KB */
+
/* Offset and size definition in flash area, used by assemble.py */
#define SECURE_IMAGE_OFFSET 0x0
#define SECURE_IMAGE_MAX_SIZE 0x80000
@@ -83,4 +87,15 @@
*/
#define FLASH_DEV_NAME Driver_FLASH0
+/* Secure Storage (SST) Service definitions */
+/* In this target the CMSIS driver requires only the offset from the base
+ * address instead of the full memory address.
+ */
+#define SST_FLASH_AREA_ADDR FLASH_SST_AREA_OFFSET
+#define SST_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE
+/* The sectors must be in consecutive memory location */
+#define SST_NBR_OF_SECTORS (FLASH_SST_AREA_SIZE / SST_SECTOR_SIZE)
+/* Specifies the smallest flash programmable unit in bytes */
+#define SST_FLASH_PROGRAM_UNIT 0x1
+
#endif /* __FLASH_LAYOUT_H__ */
diff --git a/platform/ext/target/mps2/an521/partition/flash_layout.h b/platform/ext/target/mps2/an521/partition/flash_layout.h
index 9477cf8..21b57a1 100644
--- a/platform/ext/target/mps2/an521/partition/flash_layout.h
+++ b/platform/ext/target/mps2/an521/partition/flash_layout.h
@@ -27,7 +27,8 @@
* 0x0018_0000 Secure image secondary
* 0x0020_0000 Non-secure image secondary
* 0x0028_0000 Scratch area(1 MB)
- * 0x0038_0000 Unused(0.5 MB)
+ * 0x0038_0000 Secure Storage Area (0.02 MB)
+ * 0x0038_5000 Unused(0.482 MB)
*
* Flash layout on MPS2 AN521, if BL2 not defined:
* 0x0000_0000 Secure image
@@ -71,6 +72,9 @@
#define FLASH_AREA_IMAGE_SCRATCH_OFFSET (0x280000)
#define FLASH_AREA_IMAGE_SCRATCH_SIZE (2 * FLASH_PARTITION_SIZE)
+#define FLASH_SST_AREA_OFFSET (0x380000)
+#define FLASH_SST_AREA_SIZE (0x5000) /* 20 KB */
+
/* Offset and size definition in flash area, used by assemble.py */
#define SECURE_IMAGE_OFFSET 0x0
#define SECURE_IMAGE_MAX_SIZE 0x80000
@@ -83,4 +87,15 @@
*/
#define FLASH_DEV_NAME Driver_FLASH0
+/* Secure Storage (SST) Service definitions */
+/* In this target the CMSIS driver requires only the offset from the base
+ * address instead of the full memory address.
+ */
+#define SST_FLASH_AREA_ADDR FLASH_SST_AREA_OFFSET
+#define SST_SECTOR_SIZE FLASH_AREA_IMAGE_SECTOR_SIZE
+/* The sectors must be in consecutive memory location */
+#define SST_NBR_OF_SECTORS (FLASH_SST_AREA_SIZE / SST_SECTOR_SIZE)
+/* Specifies the smallest flash programmable unit in bytes */
+#define SST_FLASH_PROGRAM_UNIT 0x1
+
#endif /* __FLASH_LAYOUT_H__ */
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 352b863..e711cd0 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -42,7 +42,7 @@
set(BUILD_CMSIS_DRIVERS On)
set(BUILD_TIME Off)
set(BUILD_UART_STDOUT On)
-set(BUILD_FLASH Off)
+set(BUILD_FLASH On)
if(NOT DEFINED PLATFORM_CMAKE_FILE)
message (FATAL_ERROR "Platform specific CMake is not defined. Please set PLATFORM_CMAKE_FILE.")
elseif(NOT EXISTS ${PLATFORM_CMAKE_FILE})
diff --git a/secure_fw/services/secure_storage/CMakeLists.inc b/secure_fw/services/secure_storage/CMakeLists.inc
index a25313b..d32c28d 100644
--- a/secure_fw/services/secure_storage/CMakeLists.inc
+++ b/secure_fw/services/secure_storage/CMakeLists.inc
@@ -38,25 +38,21 @@
if (NOT DEFINED SST_ENCRYPTION)
message(FATAL_ERROR "Incomplete build configuration: SST_ENCRYPTION is undefined. ")
endif()
+
if (NOT DEFINED SST_RAM_FS)
message(FATAL_ERROR "Incomplete build configuration: SST_RAM_FS is undefined. ")
endif()
+
if (NOT DEFINED SST_VALIDATE_METADATA_FROM_FLASH)
message(FATAL_ERROR "Incomplete build configuration: SST_VALIDATE_METADATA_FROM_FLASH is undefined. ")
endif()
set (SECURE_STORAGE_C_SRC "${SECURE_STORAGE_DIR}/sst_core.c"
- "${SECURE_STORAGE_DIR}/sst_core_interface.c"
- "${SECURE_STORAGE_DIR}/sst_asset_management.c"
- "${SECURE_STORAGE_DIR}/sst_utils.c"
- "${SECURE_STORAGE_DIR}/assets/sst_asset_defs.c"
- "${SECURE_STORAGE_DIR}/flash/sst_flash_memory_mapped.c"
- )
-
- if(NOT SST_RAM_FS)
- list(APPEND SECURE_STORAGE_C_SRC
- "${SECURE_STORAGE_DIR}/flash/sst_flash_file_mapped.c")
- endif()
+ "${SECURE_STORAGE_DIR}/sst_core_interface.c"
+ "${SECURE_STORAGE_DIR}/sst_asset_management.c"
+ "${SECURE_STORAGE_DIR}/sst_utils.c"
+ "${SECURE_STORAGE_DIR}/assets/sst_asset_defs.c"
+ "${SECURE_STORAGE_DIR}/flash/sst_flash.c")
if (SST_ENCRYPTION)
list (APPEND SECURE_STORAGE_C_SRC
diff --git a/secure_fw/services/secure_storage/flash/sst_flash.c b/secure_fw/services/secure_storage/flash/sst_flash.c
new file mode 100644
index 0000000..7d6331d
--- /dev/null
+++ b/secure_fw/services/secure_storage/flash/sst_flash.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "sst_flash.h"
+
+#include <string.h>
+#include "cmsis_compiler.h"
+#include "Driver_Flash.h"
+#include "secure_fw/services/secure_storage/sst_utils.h"
+#include "tfm_sst_defs.h"
+
+#ifndef SST_FLASH_AREA_ADDR
+#error "SST_FLASH_AREA_ADDR must be defined in flash_layout.h file"
+#endif
+
+#ifndef FLASH_DEV_NAME
+#error "FLASH_DEV_NAME must be defined in flash_layout.h file"
+#endif
+
+/* Import the CMSIS flash device driver */
+extern ARM_DRIVER_FLASH FLASH_DEV_NAME;
+
+#define BLOCK_START_OFFSET 0
+
+/*
+ * \brief Gets physical address of the given block ID.
+ *
+ * \param[in] block_id Block ID
+ * \param[in] offset Offset position from the init of the block
+ *
+ * \returns Returns physical address for the given block ID.
+ */
+__attribute__((always_inline))
+__STATIC_INLINE uint32_t get_phys_address(uint32_t block_id, uint32_t offset)
+{
+ return (SST_FLASH_AREA_ADDR + (block_id * SST_BLOCK_SIZE) + offset);
+}
+
+static enum tfm_sst_err_t flash_read(uint32_t flash_addr, uint8_t *buff,
+ uint32_t size)
+{
+ int32_t err;
+
+ err = FLASH_DEV_NAME.ReadData(flash_addr, buff, size);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_SST_ERR_SYSTEM_ERROR;
+ }
+
+ return TFM_SST_ERR_SUCCESS;
+}
+
+static enum tfm_sst_err_t flash_write(uint32_t flash_addr, const uint8_t *buff,
+ uint32_t size)
+{
+ int32_t err;
+
+ err = FLASH_DEV_NAME.ProgramData(flash_addr, buff, size);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_SST_ERR_SYSTEM_ERROR;
+ }
+
+ return TFM_SST_ERR_SUCCESS;
+}
+
+static enum tfm_sst_err_t flash_erase(uint32_t flash_addr)
+{
+ int32_t err;
+
+ err = FLASH_DEV_NAME.EraseSector(flash_addr);
+ if (err != ARM_DRIVER_OK) {
+ return TFM_SST_ERR_SYSTEM_ERROR;
+ }
+
+ return TFM_SST_ERR_SUCCESS;
+}
+
+enum tfm_sst_err_t sst_flash_read(uint32_t block_id, uint8_t *buff,
+ uint32_t offset, uint32_t size)
+{
+ uint32_t flash_addr;
+
+ /* Gets flash address location defined by block ID and offset
+ * parameters.
+ */
+ flash_addr = get_phys_address(block_id, offset);
+
+ return flash_read(flash_addr, buff, size);
+}
+
+enum tfm_sst_err_t sst_flash_write(uint32_t block_id, const uint8_t *buff,
+ uint32_t offset, uint32_t size)
+{
+ uint32_t flash_addr;
+
+ /* Gets flash address location defined by block ID and offset
+ * parameters.
+ */
+ flash_addr = get_phys_address(block_id, offset);
+
+ return flash_write(flash_addr, buff, size);
+}
+
+enum tfm_sst_err_t sst_flash_block_to_block_move(uint32_t dst_block,
+ uint32_t dst_offset,
+ uint32_t src_block,
+ uint32_t src_offset,
+ uint32_t size)
+{
+ static uint8_t dst_block_data_copy[SST_BLOCK_SIZE];
+ enum tfm_sst_err_t err;
+ uint32_t dst_flash_addr;
+ uint32_t src_flash_addr;
+
+ /* Gets flash address location defined by block ID and offset
+ * parameters.
+ */
+ src_flash_addr = get_phys_address(src_block, src_offset);
+
+ /* Reads data from source block and store it in the in-memory copy of
+ * destination content.
+ */
+ err = flash_read(src_flash_addr, dst_block_data_copy, size);
+ if (err != TFM_SST_ERR_SUCCESS) {
+ return err;
+ }
+
+ /* Gets flash address location defined by block ID and offset
+ * parameters.
+ */
+ dst_flash_addr = get_phys_address(dst_block, dst_offset);
+
+ /* Writes in flash the in-memory block content after modification */
+ err = flash_write(dst_flash_addr, dst_block_data_copy, size);
+
+ return err;
+}
+
+enum tfm_sst_err_t sst_flash_erase_block(uint32_t block_id)
+{
+ uint32_t flash_addr;
+
+ /* Calculate flash address location defined by block ID and
+ * BLOCK_START_OFFSET parameters.
+ */
+ flash_addr = get_phys_address(block_id, BLOCK_START_OFFSET);
+
+ return flash_erase(flash_addr);
+}
diff --git a/secure_fw/services/secure_storage/flash/sst_flash.h b/secure_fw/services/secure_storage/flash/sst_flash.h
index d34e5fe..87a83b4 100644
--- a/secure_fw/services/secure_storage/flash/sst_flash.h
+++ b/secure_fw/services/secure_storage/flash/sst_flash.h
@@ -10,16 +10,27 @@
#include <stdint.h>
#include "tfm_sst_defs.h"
+#include "flash_layout.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Adjust to match your system's block size */
-#define SST_BLOCK_SIZE 4096
+#ifndef SST_SECTOR_SIZE
+#error "SST_SECTOR_SIZE must be defined by the target in flash_layout.h file"
+#define SST_BLOCK_SIZE 0
+#else
+#define SST_BLOCK_SIZE SST_SECTOR_SIZE
+#endif
/* Adjust to a size that will allow all assets to fit */
-#define SST_TOTAL_NUM_OF_BLOCKS 5
+#ifndef SST_NBR_OF_SECTORS
+#error "SST_NBR_OF_SECTORS must be defined by the target in flash_layout.h file"
+#define SST_TOTAL_NUM_OF_BLOCKS 0
+#else
+#define SST_TOTAL_NUM_OF_BLOCKS SST_NBR_OF_SECTORS
+#endif
/* Default value of flash when erased */
#define SST_FLASH_DEFAULT_VAL 0xFF
@@ -47,7 +58,7 @@
uint32_t offset, uint32_t size);
/**
- * \brief Writes block data from the position specifed by block ID and offset.
+ * \brief Writes block data to the position specifed by block ID and offset.
*
* \param[in] block_id Block ID
* \param[in] buff Buffer pointer to the write data
diff --git a/secure_fw/services/secure_storage/flash/sst_flash_memory_mapped.c b/secure_fw/services/secure_storage/flash/sst_flash_memory_mapped.c
deleted file mode 100644
index fbf3cd7..0000000
--- a/secure_fw/services/secure_storage/flash/sst_flash_memory_mapped.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-#include "sst_flash.h"
-
-#include <string.h>
-#include "tfm_sst_defs.h"
-#include "secure_fw/services/secure_storage/sst_utils.h"
-
-/*************************************/
-/* Flash memory management functions */
-/*************************************/
-
-#ifdef SST_TESTS
-#define SST_DATA_VISIBLITY
-#else
-#define SST_DATA_VISIBLITY static
-#endif
-
-SST_DATA_VISIBLITY
-uint8_t block_data[SST_BLOCK_SIZE*SST_TOTAL_NUM_OF_BLOCKS] = {0};
-
-enum tfm_sst_err_t sst_flash_read(uint32_t block_id, uint8_t *buff,
- uint32_t offset, uint32_t size)
-{
- uint8_t *p_block_data;
-
- /* Calculate block data pointer to the address location defined by
- * block ID and offset parameters.
- */
- p_block_data = block_data + (block_id * SST_BLOCK_SIZE) + offset;
-
- sst_utils_memcpy(buff, p_block_data, size);
-
- return TFM_SST_ERR_SUCCESS;
-}
-
-enum tfm_sst_err_t sst_flash_write(uint32_t block_id, const uint8_t *buff,
- uint32_t offset, uint32_t size)
-{
- uint8_t *p_block_data;
-
- /* Calculate block data pointer to the address location defined by
- * block ID and offset parameters.
- */
- p_block_data = block_data + (block_id * SST_BLOCK_SIZE) + offset;
-
- sst_utils_memcpy(p_block_data, buff, size);
-
- return TFM_SST_ERR_SUCCESS;
-}
-
-enum tfm_sst_err_t sst_flash_block_to_block_move(uint32_t dst_block,
- uint32_t dst_offset,
- uint32_t src_block,
- uint32_t src_offset,
- uint32_t size)
-{
- uint8_t *p_dst_block_data;
- uint8_t *p_src_block_data;
-
- /* Calculate block data pointer to the address location defined by
- * source block ID and offset parameters.
- */
- p_src_block_data = block_data + (src_block * SST_BLOCK_SIZE) + src_offset;
-
- /* Calculate block data pointer to the address location defined by
- * source block ID and offset parameters.
- */
- p_dst_block_data = block_data + (dst_block * SST_BLOCK_SIZE) + dst_offset;
-
- sst_utils_memcpy(p_dst_block_data, p_src_block_data, size);
-
- return TFM_SST_ERR_SUCCESS;
-}
-
-enum tfm_sst_err_t sst_flash_erase_block(uint32_t block_id)
-{
- uint8_t *p_block_data;
-
- /* Calculate block data pointer to the address location defined by
- * block ID and offset parameters.
- */
- p_block_data = block_data + (block_id * SST_BLOCK_SIZE);
-
- sst_utils_memset(p_block_data, SST_FLASH_DEFAULT_VAL, SST_BLOCK_SIZE);
-
- return TFM_SST_ERR_SUCCESS;
-}
diff --git a/secure_fw/services/secure_storage/sst_core.c b/secure_fw/services/secure_storage/sst_core.c
index 75cdc2a..99f5e2d 100644
--- a/secure_fw/services/secure_storage/sst_core.c
+++ b/secure_fw/services/secure_storage/sst_core.c
@@ -64,17 +64,37 @@
#define SST_NUM_ACTIVE_DBLOCKS (SST_NUM_DEDICATED_DBLOCKS + 1)
#define SST_LOGICAL_DBLOCK0 0
+#define SST_DEFAULT_EMPTY_BUFF_VAL 0
-static struct sst_asset_system_context sst_system_ctx;
+#ifndef SST_FLASH_PROGRAM_UNIT
+#error "SST_FLASH_PROGRAM_UNIT must be defined in flash_layout.h"
+#endif
+
+/* FIXME: Support other flash program units.*/
+#if ((SST_FLASH_PROGRAM_UNIT != 1) && (SST_FLASH_PROGRAM_UNIT != 2) \
+ && (SST_FLASH_PROGRAM_UNIT != 4))
+#error "The supported SST_FLASH_PROGRAM_UNIT values are 1, 2 or 4 bytes"
+#endif
+
+#if ((SST_MAX_ASSET_SIZE % SST_FLASH_PROGRAM_UNIT) != 0)
+/* SST_ALIGNED_MAX_ASSET_SIZE aligns the SST_MAX_ASSET_SIZE with the
+ * SST_FLASH_PROGRAM_UNIT
+ */
+#define SST_ALIGNED_MAX_ASSET_SIZE \
+((SST_FLASH_PROGRAM_UNIT - (SST_MAX_ASSET_SIZE % SST_FLASH_PROGRAM_UNIT)) \
+ + SST_MAX_ASSET_SIZE)
+#else
+#define SST_ALIGNED_MAX_ASSET_SIZE SST_MAX_ASSET_SIZE
+#endif
/*
* SST data buffer is used for metadata autentication, plain text and
* encrypted data.
*/
#ifdef SST_ENCRYPTION
-static uint8_t sst_data_buf[SST_MAX_ASSET_SIZE * 2];
+static uint8_t sst_data_buf[SST_ALIGNED_MAX_ASSET_SIZE * 2];
#else
-static uint8_t sst_data_buf[SST_MAX_ASSET_SIZE];
+static uint8_t sst_data_buf[SST_ALIGNED_MAX_ASSET_SIZE];
#endif
static uint8_t *sst_buf_plain_text = sst_data_buf;
@@ -82,9 +102,11 @@
/* Plain text is stored at the beginning of SST data buffer. Encrypted data is
* located from the middle to the end of SST data buffer.
*/
-static uint8_t *sst_buf_encrypted = sst_data_buf + SST_MAX_ASSET_SIZE;
+static uint8_t *sst_buf_encrypted = sst_data_buf + SST_ALIGNED_MAX_ASSET_SIZE;
#endif
+static struct sst_asset_system_context sst_system_ctx;
+
#define SST_ALL_METADATA_SIZE \
(sizeof(struct sst_metadata_block_header) + \
(SST_NUM_ACTIVE_DBLOCKS * sizeof(struct sst_block_metadata)) + \
@@ -111,10 +133,10 @@
* created, at least, when the SST area is empty.
*/
/* Check if the largest asset fits in the asset's data area */
-#if (SST_MAX_ASSET_SIZE > SST_BLOCK_SIZE)
-#error "Current design limits maximum size of an asset to a block size"
-#elif (SST_TOTAL_NUM_OF_BLOCKS == 2)
-SST_UTILS_BOUND_CHECK(ASSET_NOT_FIT_IN_DATA_AREA, SST_MAX_ASSET_SIZE,
+SST_UTILS_BOUND_CHECK(LARGEST_ASSET_NOT_FIT_IN_DATA_BLOCK,
+ SST_ALIGNED_MAX_ASSET_SIZE, SST_BLOCK_SIZE);
+#if (SST_TOTAL_NUM_OF_BLOCKS == 2)
+SST_UTILS_BOUND_CHECK(ASSET_NOT_FIT_IN_DATA_AREA, SST_ALIGNED_MAX_ASSET_SIZE,
(SST_BLOCK_SIZE - SST_ALL_METADATA_SIZE));
#endif
@@ -122,6 +144,32 @@
SST_UTILS_BOUND_CHECK(METADATA_NOT_FIT_IN_METADATA_BLOCK,
SST_ALL_METADATA_SIZE, SST_BLOCK_SIZE);
+/**
+ * \brief Gets the number of bytes aligned with the SST_FLASH_PROGRAM_UNIT.
+ *
+ * \param[in] nbr_bytes Number of bytes to write
+ *
+ * \return Return number of bytes aligned with SST_FLASH_PROGRAM_UNIT
+ */
+static uint32_t sst_get_aligned_flash_bytes(uint32_t nbr_bytes)
+{
+ uint32_t align_flash_size;
+
+ /* Check if write parameters are aligned with the flash write
+ * program unit.
+ */
+ align_flash_size = (nbr_bytes % SST_FLASH_PROGRAM_UNIT);
+ if (align_flash_size != 0) {
+ /* Add offset to align object's size required with the flash write
+ * program unit.
+ */
+ align_flash_size = (SST_FLASH_PROGRAM_UNIT - align_flash_size);
+ }
+
+ align_flash_size += nbr_bytes;
+
+ return align_flash_size;
+}
/**
* \brief Gets offset of a logical block's metadata in metadata block
@@ -758,7 +806,8 @@
read_buf = sst_buf_plain_text;
#endif
/* Pedantic: clear the buffer from any previous residue */
- sst_utils_memset(read_buf, 0x00, SST_MAX_ASSET_SIZE);
+ sst_utils_memset(read_buf, SST_DEFAULT_EMPTY_BUFF_VAL,
+ SST_ALIGNED_MAX_ASSET_SIZE);
err = sst_flash_read(phys_block, read_buf, pos, size);
return err;
@@ -913,7 +962,8 @@
}
/* Pedantic: clear the decryption buffer */
- sst_utils_memset(sst_buf_plain_text, 0x00, SST_MAX_ASSET_SIZE);
+ sst_utils_memset(sst_buf_plain_text, SST_DEFAULT_EMPTY_BUFF_VAL,
+ SST_ALIGNED_MAX_ASSET_SIZE);
err = sst_crypto_auth_and_decrypt(&meta->crypto, 0, 0,
sst_buf_encrypted, sst_buf_plain_text,
meta->cur_size);
@@ -1192,16 +1242,19 @@
{
uint32_t i;
enum tfm_sst_err_t err;
+ uint32_t size_in_flash;
+
+ size_in_flash = sst_get_aligned_flash_bytes(size);
for (i = 0; i < SST_NUM_ACTIVE_DBLOCKS; i++) {
err = sst_meta_read_block_metadata(i, block_meta);
if (err != TFM_SST_ERR_SUCCESS) {
return TFM_SST_ERR_SYSTEM_ERROR;
}
- if (block_meta->free_size >= size) {
+ if (block_meta->free_size >= size_in_flash) {
object_meta->lblock = i;
object_meta->data_index = SST_BLOCK_SIZE - block_meta->free_size;
- block_meta->free_size -= size;
+ block_meta->free_size -= size_in_flash;
object_meta->max_size = size;
return TFM_SST_ERR_SUCCESS;
}
@@ -1313,6 +1366,7 @@
const uint8_t *prepared_buf = sst_buf_plain_text;
struct sst_assetmeta object_meta;
struct sst_block_metadata block_meta;
+ uint32_t align_flash_nbr_bytes;
/* Get the meta data index */
object_index = sst_utils_extract_index_from_handle(asset_handle);
@@ -1336,6 +1390,11 @@
return TFM_SST_ERR_PARAM_ERROR;
}
+ /* Clean previous data in sst_buf_plain_text */
+ sst_utils_memset(sst_buf_plain_text, SST_DEFAULT_EMPTY_BUFF_VAL,
+ SST_ALIGNED_MAX_ASSET_SIZE);
+
+
if (object_meta.cur_size > 0) {
/* Copy the current asset's data into the sst_buf_plain_text buffer
* or sst_buf_encrypted if SST_ENCRYPTION is enabled.
@@ -1378,10 +1437,11 @@
prepared_buf = sst_buf_encrypted;
#endif
- /* Copy the content into scratch data buffer */
+ align_flash_nbr_bytes = sst_get_aligned_flash_bytes(object_meta.cur_size);
+
err = sst_dblock_update_scratch(object_meta.lblock, &block_meta,
prepared_buf, object_meta.data_index,
- object_meta.cur_size);
+ align_flash_nbr_bytes);
if (err != TFM_SST_ERR_SUCCESS) {
return TFM_SST_ERR_SYSTEM_ERROR;
}
@@ -1553,7 +1613,7 @@
/* Save logical block, data_index and max_size to be used later on */
del_obj_lblock = object_meta.lblock;
del_obj_data_index = object_meta.data_index;
- del_obj_max_size = object_meta.max_size;
+ del_obj_max_size = sst_get_aligned_flash_bytes(object_meta.max_size);
/* Remove object metadata */
object_meta.unique_id = SST_INVALID_UUID;
@@ -1596,7 +1656,8 @@
object_meta.data_index -= del_obj_max_size;
/* Increase number of bytes to move */
- nbr_bytes_to_move += object_meta.max_size;
+ nbr_bytes_to_move += sst_get_aligned_flash_bytes(
+ object_meta.max_size);
}
}
/* Update object's metadata in to the scratch block */
@@ -1861,7 +1922,8 @@
}
/* Initialize object metadata table */
- sst_utils_memset(&object_metadata, 0x00, sizeof(struct sst_assetmeta));
+ sst_utils_memset(&object_metadata, SST_DEFAULT_EMPTY_BUFF_VAL,
+ sizeof(struct sst_assetmeta));
for (i = 0; i < SST_NUM_ASSETS; i++) {
/* In the beginning phys id is same as logical id */
/* Update object's metadata to reflect new attributes */
diff --git a/secure_fw/services/secure_storage/sst_utils.h b/secure_fw/services/secure_storage/sst_utils.h
index 0c72ba9..b25827e 100644
--- a/secure_fw/services/secure_storage/sst_utils.h
+++ b/secure_fw/services/secure_storage/sst_utils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
@@ -8,6 +8,8 @@
#ifndef __SST_UTILS_H__
#define __SST_UTILS_H__
+#include <stdint.h>
+
#ifdef __cplusplus
extern "C" {
#endif