From 73d4a1edc31e9881e4cd7c38ea2868dac0a6edfb Mon Sep 17 00:00:00 2001 From: Taras Drozdovskyi Date: Tue, 30 Jul 2024 09:11:31 +0300 Subject: [PATCH] feat: Replaced gcc allocator with FreeRTOS allocator for secure world Signed-off-by: Taras Drozdovskyi --- .../src/numaker_pfm_m2351/secure/Makefile | 4 +- arch/riscv32/Kconfig | 8 +- common/Makefile | 52 ++ common/heap_4.c | 555 ++++++++++++++++++ crypto/Makefile | 3 + crypto/libtomcrypt/src/tee_ltc_provider.c | 20 +- tee/kernel/pseudo_ta.c | 2 +- tee/kernel/tee_ta_manager.c | 7 +- tee/kernel/user_ta.c | 2 +- tee/lib/libutee/tee_api_operations.c | 4 +- tee/lib/libutee/tee_user_mem.c | 54 +- tee/tee/tee_obj.c | 4 +- tee/tee/tee_pobj.c | 14 +- tee/tee/tee_svc_cryp.c | 6 +- tee_client/libteec/src/tee_client_api.c | 2 + 15 files changed, 667 insertions(+), 70 deletions(-) create mode 100644 common/Makefile create mode 100644 common/heap_4.c diff --git a/arch/cortex-m23/m2351/src/numaker_pfm_m2351/secure/Makefile b/arch/cortex-m23/m2351/src/numaker_pfm_m2351/secure/Makefile index cc825c8a..c4804620 100644 --- a/arch/cortex-m23/m2351/src/numaker_pfm_m2351/secure/Makefile +++ b/arch/cortex-m23/m2351/src/numaker_pfm_m2351/secure/Makefile @@ -30,7 +30,6 @@ CFLAGS += -I../../Device/Nuvoton/M2351/Include CFLAGS += -I$(TOPDIR)/tee_client/public CFLAGS += -I$(TOPDIR)/tee_client/libteec/include/freertos CFLAGS += -I$(TOPDIR)/tee/lib/libutee/include - CFLAGS += -I$(TOPDIR)/tee/lib/libutils/ext/include CFLAGS += -I$(TOPDIR)/tee/lib/libutils/isoc/include CFLAGS += -I$(TOPDIR)/tee/include @@ -67,7 +66,7 @@ OBJS_S = $(AOBJS_S) $(COBJS_S) LIBPATHS = -L. -L"$(TOPDIR)/lib" -LIBS = -lm -lc -lnosys -lm2351_StdDriver_s -lcrypt_s +LIBS = -lm -lc -lnosys -lm2351_StdDriver_s -lalloc_s -lcrypt_s $(AOBJS_S): $(OBJDIR)/%$(OBJEXT): %.S $(Q) mkdir -p $(OBJDIR)/$(dir $<) @@ -81,6 +80,7 @@ $(COBJS_S): $(OBJDIR)/%$(OBJEXT): %.c mtower_s$(EXEEXT): $(OBJS_S) $(Q) $(MAKE) -C ../../StdDriver/src/ TOPDIR="$(TOPDIR)" WORLD=secure libm2351_StdDriver_s.a + $(Q) $(MAKE) -C $(TOPDIR)/common/ TOPDIR="$(TOPDIR)" WORLD=secure liballoc_s.a $(Q) $(MAKE) -C $(TOPDIR)/crypto/ TOPDIR="$(TOPDIR)" WORLD=secure libcrypt_s.a @echo "CC: mTower_s$(EXEEXT)" $(Q) $(CC) $(CFLAGS) -mcmse -Wl,--section-start=.text=$(CONFIG_START_ADDRESS_BL32) -Tsecure.ld $(OBJS_S) $(LIBPATHS) $(LIBS) -o $(OBJDIR)/bl32.elf diff --git a/arch/riscv32/Kconfig b/arch/riscv32/Kconfig index 5966ff7b..cd20ca5d 100644 --- a/arch/riscv32/Kconfig +++ b/arch/riscv32/Kconfig @@ -29,8 +29,8 @@ comment "FE310 Configuration Options" source arch/riscv32/fe310/Kconfig endif -if ARCH_FAMILY_BL808 -comment "BL808 Configuration Options" -source arch/riscv32/bl808/Kconfig -endif +# if ARCH_FAMILY_BL808 +# comment "BL808 Configuration Options" +# source arch/riscv32/bl808/Kconfig +# endif \ No newline at end of file diff --git a/common/Makefile b/common/Makefile new file mode 100644 index 00000000..af67e63c --- /dev/null +++ b/common/Makefile @@ -0,0 +1,52 @@ +############################################################################ +# common/Makefile +# +# Copyright (c) 2024 Samsung Electronics Co., Ltd. All Rights Reserved. +# Author: Taras Drozdovskyi t.drozdovsky@samsung.com +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +############################################################################ + +-include $(TOPDIR)/Make.defs +-include $(TOPDIR)/.config + +CFLAGS += -I. +CFLAGS += -I$(TOPDIR)/include/mtower + +ifeq ($(WORLD), secure) +CFLAGS += -mcmse +endif + +SRCS = heap_4.c + +ifeq ($(WORLD), secure) +CFLAGS += -DDEBUG_PORT=$(subst ",,$(CONFIG_SECURE_DEBUG_UART)) +OBJDIR = $(TOPDIR)/build/secure$(subst $(TOPDIR),,$(shell pwd)) +endif + +OBJS = $(addprefix $(OBJDIR)/, $(SRCS:.c=.o)) + +current_dir = $(subst $(TOPDIR),,$(shell pwd)) + +$(OBJDIR)/%.o : %.c + $(Q) mkdir -p $(OBJDIR)/$(dir $<) + @echo "CC: $<" + $(Q) $(CC) $(CFLAGS) -c -o $@ $^ + +liballoc_s.a: $(OBJS) + $(Q) $(AR) $(OBJDIR)/$@ $(OBJS) + $(Q) cp $(OBJDIR)/$@ $(TOPDIR)/lib/$@ + +clean: + rm -f $(OBJS) liballoc_s.a diff --git a/common/heap_4.c b/common/heap_4.c new file mode 100644 index 00000000..f6ce0fa3 --- /dev/null +++ b/common/heap_4.c @@ -0,0 +1,555 @@ +/* + * FreeRTOS Kernel V10.4.6 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * 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, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * 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. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +/* + * A sample implementation of pvPortMalloc() and vPortFree() that combines + * (coalescences) adjacent memory blocks as they are freed, and in so doing + * limits memory fragmentation. + * + * See heap_1.c, heap_2.c and heap_3.c for alternative implementations, and the + * memory management pages of https://www.FreeRTOS.org for more information. + */ +#include +#include +// #include "portable.h" +// #include "portmacro.h" + +/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining + * all the API functions to use the MPU wrappers. That should only be done when + * task.h is included from an application file. */ +// #define MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +// #include "FreeRTOS.h" +// #include "task.h" + +// #undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE + +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE 8000 +#define configAPPLICATION_ALLOCATED_HEAP 0 + +#define PRIVILEGED_FUNCTION +#define PRIVILEGED_DATA +#define portBYTE_ALIGNMENT 8 +#if portBYTE_ALIGNMENT == 32 + #define portBYTE_ALIGNMENT_MASK ( 0x001f ) +#elif portBYTE_ALIGNMENT == 16 + #define portBYTE_ALIGNMENT_MASK ( 0x000f ) +#elif portBYTE_ALIGNMENT == 8 + #define portBYTE_ALIGNMENT_MASK ( 0x0007 ) +#elif portBYTE_ALIGNMENT == 4 + #define portBYTE_ALIGNMENT_MASK ( 0x0003 ) +#elif portBYTE_ALIGNMENT == 2 + #define portBYTE_ALIGNMENT_MASK ( 0x0001 ) +#elif portBYTE_ALIGNMENT == 1 + #define portBYTE_ALIGNMENT_MASK ( 0x0000 ) +#else /* if portBYTE_ALIGNMENT == 32 */ + #error "Invalid portBYTE_ALIGNMENT definition" +#endif /* if portBYTE_ALIGNMENT == 32 */ + +/* Used to pass information about the heap out of vPortGetHeapStats(). */ +typedef struct xHeapStats +{ + size_t xAvailableHeapSpaceInBytes; /* The total heap size currently available - this is the sum of all the free blocks, not the largest block that can be allocated. */ + size_t xSizeOfLargestFreeBlockInBytes; /* The maximum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ + size_t xSizeOfSmallestFreeBlockInBytes; /* The minimum size, in bytes, of all the free blocks within the heap at the time vPortGetHeapStats() is called. */ + size_t xNumberOfFreeBlocks; /* The number of free memory blocks within the heap at the time vPortGetHeapStats() is called. */ + size_t xMinimumEverFreeBytesRemaining; /* The minimum amount of total free memory (sum of all free blocks) there has been in the heap since the system booted. */ + size_t xNumberOfSuccessfulAllocations; /* The number of calls to pvPortMalloc() that have returned a valid memory block. */ + size_t xNumberOfSuccessfulFrees; /* The number of calls to vPortFree() that has successfully freed a block of memory. */ +} HeapStats_t; + +#if( configUSE_16_BIT_TICKS == 1 ) +typedef uint16_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffff +#else +typedef uint32_t TickType_t; +#define portMAX_DELAY ( TickType_t ) 0xffffffffUL + +/* 32-bit tick type on a 32-bit architecture, so reads of the tick count do + not need to be guarded with a critical section. */ +#define portTICK_TYPE_IS_ATOMIC 1 +#endif + + +#if ( configSUPPORT_DYNAMIC_ALLOCATION == 0 ) + #error This file must not be used if configSUPPORT_DYNAMIC_ALLOCATION is 0 +#endif + +/* Block sizes must not get too small. */ +#define heapMINIMUM_BLOCK_SIZE ( ( size_t ) ( xHeapStructSize << 1 ) ) + +/* Assumes 8bit bytes! */ +#define heapBITS_PER_BYTE ( ( size_t ) 8 ) + +/* Allocate the memory for the heap. */ +#if ( configAPPLICATION_ALLOCATED_HEAP == 1 ) + +/* The application writer has already defined the array used for the RTOS +* heap - probably so it can be placed in a special segment or address. */ + extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#else + PRIVILEGED_DATA static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ]; +#endif /* configAPPLICATION_ALLOCATED_HEAP */ + +/* Define the linked list structure. This is used to link free blocks in order + * of their memory address. */ +typedef struct A_BLOCK_LINK +{ + struct A_BLOCK_LINK * pxNextFreeBlock; /*<< The next free block in the list. */ + size_t xBlockSize; /*<< The size of the free block. */ +} BlockLink_t; + +/*-----------------------------------------------------------*/ + +/* + * Inserts a block of memory that is being freed into the correct position in + * the list of free memory blocks. The block being freed will be merged with + * the block in front it and/or the block behind it if the memory blocks are + * adjacent to each other. + */ +static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) PRIVILEGED_FUNCTION; + +/* + * Called automatically to setup the required heap structures the first time + * pvPortMalloc() is called. + */ +static void prvHeapInit( void ) PRIVILEGED_FUNCTION; + +/*-----------------------------------------------------------*/ + +/* The size of the structure placed at the beginning of each allocated memory + * block must by correctly byte aligned. */ +static const size_t xHeapStructSize = ( sizeof( BlockLink_t ) + ( ( size_t ) ( portBYTE_ALIGNMENT - 1 ) ) ) & ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + +/* Create a couple of list links to mark the start and end of the list. */ +PRIVILEGED_DATA static BlockLink_t xStart, * pxEnd = NULL; + +/* Keeps track of the number of calls to allocate and free memory as well as the + * number of free bytes remaining, but says nothing about fragmentation. */ +PRIVILEGED_DATA static size_t xFreeBytesRemaining = 0U; +PRIVILEGED_DATA static size_t xMinimumEverFreeBytesRemaining = 0U; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulAllocations = 0; +PRIVILEGED_DATA static size_t xNumberOfSuccessfulFrees = 0; + +/* Gets set to the top bit of an size_t type. When this bit in the xBlockSize + * member of an BlockLink_t structure is set then the block belongs to the + * application. When the bit is free the block is still part of the free heap + * space. */ +PRIVILEGED_DATA static size_t xBlockAllocatedBit = 0; + +/*-----------------------------------------------------------*/ + +void * pvPortMalloc( size_t xWantedSize ) +{ + BlockLink_t * pxBlock, * pxPreviousBlock, * pxNewBlockLink; + void * pvReturn = NULL; + + // vTaskSuspendAll(); + { + /* If this is the first call to malloc then the heap will require + * initialisation to setup the list of free blocks. */ + if( pxEnd == NULL ) + { + prvHeapInit(); + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + + /* Check the requested block size is not so large that the top bit is + * set. The top bit of the block size member of the BlockLink_t structure + * is used to determine who owns the block - the application or the + * kernel, so it must be free. */ + if( ( xWantedSize & xBlockAllocatedBit ) == 0 ) + { + /* The wanted size must be increased so it can contain a BlockLink_t + * structure in addition to the requested amount of bytes. */ + if( ( xWantedSize > 0 ) && + ( ( xWantedSize + xHeapStructSize ) > xWantedSize ) ) /* Overflow check */ + { + xWantedSize += xHeapStructSize; + + /* Ensure that blocks are always aligned. */ + if( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) != 0x00 ) + { + /* Byte alignment required. Check for overflow. */ + if( ( xWantedSize + ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ) ) + > xWantedSize ) + { + xWantedSize += ( portBYTE_ALIGNMENT - ( xWantedSize & portBYTE_ALIGNMENT_MASK ) ); + // configASSERT( ( xWantedSize & portBYTE_ALIGNMENT_MASK ) == 0 ); + } + else + { + xWantedSize = 0; + } + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + } + else + { + xWantedSize = 0; + } + + if( ( xWantedSize > 0 ) && ( xWantedSize <= xFreeBytesRemaining ) ) + { + /* Traverse the list from the start (lowest address) block until + * one of adequate size is found. */ + pxPreviousBlock = &xStart; + pxBlock = xStart.pxNextFreeBlock; + + while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock != NULL ) ) + { + pxPreviousBlock = pxBlock; + pxBlock = pxBlock->pxNextFreeBlock; + } + + /* If the end marker was reached then a block of adequate size + * was not found. */ + if( pxBlock != pxEnd ) + { + /* Return the memory space pointed to - jumping over the + * BlockLink_t structure at its start. */ + pvReturn = ( void * ) ( ( ( uint8_t * ) pxPreviousBlock->pxNextFreeBlock ) + xHeapStructSize ); + + /* This block is being returned for use so must be taken out + * of the list of free blocks. */ + pxPreviousBlock->pxNextFreeBlock = pxBlock->pxNextFreeBlock; + + /* If the block is larger than required it can be split into + * two. */ + if( ( pxBlock->xBlockSize - xWantedSize ) > heapMINIMUM_BLOCK_SIZE ) + { + /* This block is to be split into two. Create a new + * block following the number of bytes requested. The void + * cast is used to prevent byte alignment warnings from the + * compiler. */ + pxNewBlockLink = ( void * ) ( ( ( uint8_t * ) pxBlock ) + xWantedSize ); + // configASSERT( ( ( ( size_t ) pxNewBlockLink ) & portBYTE_ALIGNMENT_MASK ) == 0 ); + + /* Calculate the sizes of two blocks split from the + * single block. */ + pxNewBlockLink->xBlockSize = pxBlock->xBlockSize - xWantedSize; + pxBlock->xBlockSize = xWantedSize; + + /* Insert the new block into the list of free blocks. */ + prvInsertBlockIntoFreeList( pxNewBlockLink ); + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + + xFreeBytesRemaining -= pxBlock->xBlockSize; + + if( xFreeBytesRemaining < xMinimumEverFreeBytesRemaining ) + { + xMinimumEverFreeBytesRemaining = xFreeBytesRemaining; + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + + /* The block is being returned - it is allocated and owned + * by the application and has no "next" block. */ + pxBlock->xBlockSize |= xBlockAllocatedBit; + pxBlock->pxNextFreeBlock = NULL; + xNumberOfSuccessfulAllocations++; + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + + // traceMALLOC( pvReturn, xWantedSize ); + } + // ( void ) xTaskResumeAll(); + + #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) + { + if( pvReturn == NULL ) + { + extern void vApplicationMallocFailedHook( void ); + vApplicationMallocFailedHook(); + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + } + #endif /* if ( configUSE_MALLOC_FAILED_HOOK == 1 ) */ + + // configASSERT( ( ( ( size_t ) pvReturn ) & ( size_t ) portBYTE_ALIGNMENT_MASK ) == 0 ); + return pvReturn; +} +/*-----------------------------------------------------------*/ + +void vPortFree( void * pv ) +{ + uint8_t * puc = ( uint8_t * ) pv; + BlockLink_t * pxLink; + + if( pv != NULL ) + { + /* The memory being freed will have an BlockLink_t structure immediately + * before it. */ + puc -= xHeapStructSize; + + /* This casting is to keep the compiler from issuing warnings. */ + pxLink = ( void * ) puc; + + /* Check the block is actually allocated. */ + // configASSERT( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ); + // configASSERT( pxLink->pxNextFreeBlock == NULL ); + + if( ( pxLink->xBlockSize & xBlockAllocatedBit ) != 0 ) + { + if( pxLink->pxNextFreeBlock == NULL ) + { + /* The block is being returned to the heap - it is no longer + * allocated. */ + pxLink->xBlockSize &= ~xBlockAllocatedBit; + + // vTaskSuspendAll(); + { + /* Add this block to the list of free blocks. */ + xFreeBytesRemaining += pxLink->xBlockSize; + // traceFREE( pv, pxLink->xBlockSize ); + prvInsertBlockIntoFreeList( ( ( BlockLink_t * ) pxLink ) ); + xNumberOfSuccessfulFrees++; + } + // ( void ) xTaskResumeAll(); + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + } +} +/*-----------------------------------------------------------*/ + +size_t xPortGetFreeHeapSize( void ) +{ + return xFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +size_t xPortGetMinimumEverFreeHeapSize( void ) +{ + return xMinimumEverFreeBytesRemaining; +} +/*-----------------------------------------------------------*/ + +void vPortInitialiseBlocks( void ) +{ + /* This just exists to keep the linker quiet. */ +} +/*-----------------------------------------------------------*/ + +static void prvHeapInit( void ) /* PRIVILEGED_FUNCTION */ +{ + BlockLink_t * pxFirstFreeBlock; + uint8_t * pucAlignedHeap; + size_t uxAddress; + size_t xTotalHeapSize = configTOTAL_HEAP_SIZE; + + /* Ensure the heap starts on a correctly aligned boundary. */ + uxAddress = ( size_t ) ucHeap; + + if( ( uxAddress & portBYTE_ALIGNMENT_MASK ) != 0 ) + { + uxAddress += ( portBYTE_ALIGNMENT - 1 ); + uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + xTotalHeapSize -= uxAddress - ( size_t ) ucHeap; + } + + pucAlignedHeap = ( uint8_t * ) uxAddress; + + /* xStart is used to hold a pointer to the first item in the list of free + * blocks. The void cast is used to prevent compiler warnings. */ + xStart.pxNextFreeBlock = ( void * ) pucAlignedHeap; + xStart.xBlockSize = ( size_t ) 0; + + /* pxEnd is used to mark the end of the list of free blocks and is inserted + * at the end of the heap space. */ + uxAddress = ( ( size_t ) pucAlignedHeap ) + xTotalHeapSize; + uxAddress -= xHeapStructSize; + uxAddress &= ~( ( size_t ) portBYTE_ALIGNMENT_MASK ); + pxEnd = ( void * ) uxAddress; + pxEnd->xBlockSize = 0; + pxEnd->pxNextFreeBlock = NULL; + + /* To start with there is a single free block that is sized to take up the + * entire heap space, minus the space taken by pxEnd. */ + pxFirstFreeBlock = ( void * ) pucAlignedHeap; + pxFirstFreeBlock->xBlockSize = uxAddress - ( size_t ) pxFirstFreeBlock; + pxFirstFreeBlock->pxNextFreeBlock = pxEnd; + + /* Only one block exists - and it covers the entire usable heap space. */ + xMinimumEverFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + xFreeBytesRemaining = pxFirstFreeBlock->xBlockSize; + + /* Work out the position of the top bit in a size_t variable. */ + xBlockAllocatedBit = ( ( size_t ) 1 ) << ( ( sizeof( size_t ) * heapBITS_PER_BYTE ) - 1 ); +} +/*-----------------------------------------------------------*/ + +static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVILEGED_FUNCTION */ +{ + BlockLink_t * pxIterator; + uint8_t * puc; + + /* Iterate through the list until a block is found that has a higher address + * than the block being inserted. */ + for( pxIterator = &xStart; pxIterator->pxNextFreeBlock < pxBlockToInsert; pxIterator = pxIterator->pxNextFreeBlock ) + { + /* Nothing to do here, just iterate to the right position. */ + } + + /* Do the block being inserted, and the block it is being inserted after + * make a contiguous block of memory? */ + puc = ( uint8_t * ) pxIterator; + + if( ( puc + pxIterator->xBlockSize ) == ( uint8_t * ) pxBlockToInsert ) + { + pxIterator->xBlockSize += pxBlockToInsert->xBlockSize; + pxBlockToInsert = pxIterator; + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } + + /* Do the block being inserted, and the block it is being inserted before + * make a contiguous block of memory? */ + puc = ( uint8_t * ) pxBlockToInsert; + + if( ( puc + pxBlockToInsert->xBlockSize ) == ( uint8_t * ) pxIterator->pxNextFreeBlock ) + { + if( pxIterator->pxNextFreeBlock != pxEnd ) + { + /* Form one big block from the two blocks. */ + pxBlockToInsert->xBlockSize += pxIterator->pxNextFreeBlock->xBlockSize; + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock->pxNextFreeBlock; + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxEnd; + } + } + else + { + pxBlockToInsert->pxNextFreeBlock = pxIterator->pxNextFreeBlock; + } + + /* If the block being inserted plugged a gab, so was merged with the block + * before and the block after, then it's pxNextFreeBlock pointer will have + * already been set, and should not be set here as that would make it point + * to itself. */ + if( pxIterator != pxBlockToInsert ) + { + pxIterator->pxNextFreeBlock = pxBlockToInsert; + } + else + { + // mtCOVERAGE_TEST_MARKER(); + } +} +/*-----------------------------------------------------------*/ + +void vPortGetHeapStats( HeapStats_t * pxHeapStats ) +{ + BlockLink_t * pxBlock; + size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */ + + // vTaskSuspendAll(); + { + pxBlock = xStart.pxNextFreeBlock; + + /* pxBlock will be NULL if the heap has not been initialised. The heap + * is initialised automatically when the first allocation is made. */ + if( pxBlock != NULL ) + { + do + { + /* Increment the number of blocks and record the largest block seen + * so far. */ + xBlocks++; + + if( pxBlock->xBlockSize > xMaxSize ) + { + xMaxSize = pxBlock->xBlockSize; + } + + if( pxBlock->xBlockSize < xMinSize ) + { + xMinSize = pxBlock->xBlockSize; + } + + /* Move to the next block in the chain until the last block is + * reached. */ + pxBlock = pxBlock->pxNextFreeBlock; + } while( pxBlock != pxEnd ); + } + } + // ( void ) xTaskResumeAll(); + + pxHeapStats->xSizeOfLargestFreeBlockInBytes = xMaxSize; + pxHeapStats->xSizeOfSmallestFreeBlockInBytes = xMinSize; + pxHeapStats->xNumberOfFreeBlocks = xBlocks; + + // taskENTER_CRITICAL(); + { + pxHeapStats->xAvailableHeapSpaceInBytes = xFreeBytesRemaining; + pxHeapStats->xNumberOfSuccessfulAllocations = xNumberOfSuccessfulAllocations; + pxHeapStats->xNumberOfSuccessfulFrees = xNumberOfSuccessfulFrees; + pxHeapStats->xMinimumEverFreeBytesRemaining = xMinimumEverFreeBytesRemaining; + } + // taskEXIT_CRITICAL(); +} diff --git a/crypto/Makefile b/crypto/Makefile index ebb4096d..28157ec7 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -85,6 +85,9 @@ CFLAGS += -D_CFG_CRYPTO_WITH_HASH -DCFG_CRYPTO_SHA1 -DCFG_CRYPTO_HMAC CFLAGS += -D_CFG_CRYPTO_WITH_MAC +CFLAGS += -DXMALLOC=pvPortMalloc +CFLAGS += -DXFREE=vPortFree + ifneq ($(WORLD), secure) CFLAGS += -DDEBUG_PORT=$(subst ",,$(CONFIG_NONSECURE_DEBUG_UART)) OBJDIR = $(TOPDIR)/build/nonsecure$(subst $(TOPDIR),,$(shell pwd)) diff --git a/crypto/libtomcrypt/src/tee_ltc_provider.c b/crypto/libtomcrypt/src/tee_ltc_provider.c index 95c977ce..5dff667b 100644 --- a/crypto/libtomcrypt/src/tee_ltc_provider.c +++ b/crypto/libtomcrypt/src/tee_ltc_provider.c @@ -409,7 +409,7 @@ void crypto_hash_free_ctx(void *ctx, uint32_t algo __unused) */ if (ctx) assert(!hash_get_ctx_size(algo, &ctx_size)); - free(ctx); + TEE_Free(ctx); } void crypto_hash_copy_state(void *dst_ctx, void *src_ctx, uint32_t algo) @@ -708,7 +708,7 @@ struct bignum *crypto_bignum_allocate(size_t size_bits) void crypto_bignum_free(struct bignum *s) { - free(s); + TEE_Free(s); } void crypto_bignum_clear(struct bignum *s) @@ -841,7 +841,7 @@ static TEE_Result rsadorep(rsa_key *ltc_key, const uint8_t *src, */ blen = (mpa_StaticTempVarSizeInU32(LTC_MAX_BITS_PER_VARIABLE)) * sizeof(uint32_t); - buf = malloc(blen); + buf = TEE_Malloc(blen, TEE_MALLOC_FILL_ZERO); if (!buf) { res = TEE_ERROR_OUT_OF_MEMORY; goto out; @@ -883,7 +883,7 @@ static TEE_Result rsadorep(rsa_key *ltc_key, const uint8_t *src, out: if (buf) - free(buf); + TEE_Free(buf); return res; } @@ -972,7 +972,7 @@ TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key, ltc_rsa_algo = LTC_PKCS_1_OAEP; } - buf = malloc(blen); + buf = TEE_Malloc(blen, TEE_MALLOC_FILL_ZERO); if (!buf) { res = TEE_ERROR_OUT_OF_MEMORY; goto out; @@ -1017,7 +1017,7 @@ TEE_Result crypto_acipher_rsaes_decrypt(uint32_t algo, struct rsa_keypair *key, out: if (buf) - free(buf); + TEE_Free(buf); return res; } @@ -2019,7 +2019,7 @@ void crypto_cipher_free_ctx(void *ctx, uint32_t algo __maybe_unused) */ if (ctx) assert(!cipher_get_ctx_size(algo, &ctx_size)); - free(ctx); + TEE_Free(ctx); } void crypto_cipher_copy_state(void *dst_ctx, void *src_ctx, uint32_t algo) @@ -2372,7 +2372,7 @@ void crypto_mac_free_ctx(void *ctx, uint32_t algo __maybe_unused) */ if (ctx) assert(!mac_get_ctx_size(algo, &ctx_size)); - free(ctx); + TEE_Free(ctx); } void crypto_mac_copy_state(void *dst_ctx, void *src_ctx, uint32_t algo) @@ -2651,7 +2651,7 @@ TEE_Result crypto_aes_ccm_alloc_ctx(void **ctx_ret) void crypto_aes_ccm_free_ctx(void *ctx) { - free(ctx); + TEE_Free(ctx); } void crypto_aes_ccm_copy_state(void *dst_ctx, void *src_ctx) @@ -2832,7 +2832,7 @@ TEE_Result crypto_aes_gcm_alloc_ctx(void **ctx_ret) void crypto_aes_gcm_free_ctx(void *ctx) { - free(ctx); + TEE_Free(ctx); } void crypto_aes_gcm_copy_state(void *dst_ctx, void *src_ctx) diff --git a/tee/kernel/pseudo_ta.c b/tee/kernel/pseudo_ta.c index cdb2f236..1b0a5b6d 100644 --- a/tee/kernel/pseudo_ta.c +++ b/tee/kernel/pseudo_ta.c @@ -251,7 +251,7 @@ static void pseudo_ta_enter_close_session(struct tee_ta_session *s) static void pseudo_ta_destroy(struct tee_ta_ctx *ctx) { - free(to_pseudo_ta_ctx(ctx)); + TEE_Free(to_pseudo_ta_ctx(ctx)); } static const struct tee_ta_ops pseudo_ta_ops = { diff --git a/tee/kernel/tee_ta_manager.c b/tee/kernel/tee_ta_manager.c index 051566e8..2cadb4d2 100644 --- a/tee/kernel/tee_ta_manager.c +++ b/tee/kernel/tee_ta_manager.c @@ -444,7 +444,7 @@ TEE_Result tee_ta_close_session(struct tee_ta_session *csess, //#if defined(CFG_TA_GPROF_SUPPORT) // free(sess->sbuf); //#endif - free(sess); + TEE_Free(sess); // tee_ta_clear_busy(ctx); // @@ -517,7 +517,6 @@ static TEE_Result tee_ta_init_session(TEE_ErrorOrigin *err, memset(s,0,sizeof(struct tee_ta_session)); -// // s->cancel_mask = true; // condvar_init(&s->refc_cv); // condvar_init(&s->lock_cv); @@ -556,12 +555,12 @@ static TEE_Result tee_ta_init_session(TEE_ErrorOrigin *err, *sess = s; } else { TAILQ_REMOVE(open_sessions, s, link); - free(s); + TEE_Free(s); } // mutex_unlock(&tee_ta_mutex); return res; } -// + TEE_Result tee_ta_open_session(TEE_ErrorOrigin *err, struct tee_ta_session **sess, struct tee_ta_session_head *open_sessions, diff --git a/tee/kernel/user_ta.c b/tee/kernel/user_ta.c index d4395c9e..fcdbc0f1 100644 --- a/tee/kernel/user_ta.c +++ b/tee/kernel/user_ta.c @@ -732,7 +732,7 @@ static void user_ta_ctx_destroy(struct tee_ta_ctx *ctx) tee_obj_close_all(utc); // /* Free emums created by this TA */ // tee_svc_storage_close_all_enum(utc); - free(utc); + TEE_Free(utc); } //static uint32_t user_ta_get_instance_id(struct tee_ta_ctx *ctx) diff --git a/tee/lib/libutee/tee_api_operations.c b/tee/lib/libutee/tee_api_operations.c index 890c73fa..210b57db 100644 --- a/tee/lib/libutee/tee_api_operations.c +++ b/tee/lib/libutee/tee_api_operations.c @@ -306,7 +306,7 @@ TEE_Result TEE_AllocateOperation(TEE_OperationHandle *operation, return TEE_ERROR_OUT_OF_MEMORY; void *cp = NULL; - cp = malloc(sizeof(struct oprtn_hndl_elem)); + cp = TEE_Malloc(sizeof(struct oprtn_hndl_elem), TEE_MALLOC_FILL_ZERO); if (!cp) { TEE_Free(op); return TEE_ERROR_OUT_OF_MEMORY; @@ -431,7 +431,7 @@ void TEE_FreeOperation(TEE_OperationHandle operation) e = get_operation_elem(operation); if (e != NULL) { TAILQ_REMOVE(&oprtn_hndl_head, e, link); - free(e); + TEE_Free(e); } TEE_Free(operation); } diff --git a/tee/lib/libutee/tee_user_mem.c b/tee/lib/libutee/tee_user_mem.c index cd9fdfaa..8bd57b62 100644 --- a/tee/lib/libutee/tee_user_mem.c +++ b/tee/lib/libutee/tee_user_mem.c @@ -43,14 +43,9 @@ #define CFG_TEE_CORE_USER_MEM_DEBUG 0 -extern volatile __HeapBase; -extern volatile __HeapLimit; - void *tee_user_mem_alloc(size_t len, uint32_t hint) { uint8_t *p; - void* limit = &__HeapLimit; - void* base = &__HeapBase; switch (hint) { case TEE_MALLOC_FILL_ZERO: @@ -60,18 +55,8 @@ void *tee_user_mem_alloc(size_t len, uint32_t hint) EMSG("Invalid alloc hint [%X]", (unsigned int)hint); return NULL; } - // printf("malloc = base = %x\n", base ); - // printf("malloc = (limit - base)/2 = %x\n", (limit - base)/2 ); - if ((limit - base)/2 < len + 8) - return NULL; - // p = utee_malloc(len); - p = malloc(len); - // printf("malloc 1 = base + ((limit - base)/2) = %x\n", base + ((limit - base)/2) ); - // printf("malloc 2 = p + len = %x\n", p + len ); - if ( base + ((limit - base)/2) < p + len) { - free(p); - return NULL; - } + p = pvPortMalloc(len); + // printf("malloc p = %p\r\n", p); if (p == NULL) return NULL; @@ -84,26 +69,27 @@ void *tee_user_mem_alloc(size_t len, uint32_t hint) return p; } -void *tee_user_mem_realloc(void *buffer, size_t len) -{ - uint8_t *p; - void* limit = &__HeapLimit; - void* base = &__HeapBase; - - if ((limit - base)/2 < len + 8) - return NULL; - p = realloc(buffer, len); - if ( base + ((limit - base)/2) < p + len) { - free(p); - return NULL; - } -// return utee_realloc(buffer, len); - return p; -} +// void *tee_user_mem_realloc(void *buffer, size_t len) +// { +// uint8_t *p; +// void* limit = &__HeapLimit; +// void* base = &__HeapBase; + +// if ((limit - base)/2 < len + 8) +// return NULL; +// p = realloc(buffer, len); +// if ( base + ((limit - base)/2) < p + len) { +// free(p); +// return NULL; +// } +// // return utee_realloc(buffer, len); +// return p; +// } void tee_user_mem_free(void *buffer) { - free(buffer); + // printf("free p = %p\r\n", buffer); + vPortFree(buffer); // utee_free(buffer); } diff --git a/tee/tee/tee_obj.c b/tee/tee/tee_obj.c index 0fc9953f..9ba2fb70 100644 --- a/tee/tee/tee_obj.c +++ b/tee/tee/tee_obj.c @@ -107,7 +107,7 @@ void tee_obj_free(struct tee_obj *o) { if (o) { tee_obj_attr_free(o); - free(o->attr); - free(o); + TEE_Free(o->attr); + TEE_Free(o); } } diff --git a/tee/tee/tee_pobj.c b/tee/tee/tee_pobj.c index 8dc55e53..a98a0584 100644 --- a/tee/tee/tee_pobj.c +++ b/tee/tee/tee_pobj.c @@ -126,9 +126,9 @@ TEE_Result tee_pobj_get(TEE_UUID *uuid, void *obj_id, uint32_t obj_id_len, o->fops = fops; o->temporary = temporary; - o->obj_id = malloc(obj_id_len); + o->obj_id = TEE_Malloc(obj_id_len, TEE_MALLOC_FILL_ZERO); if (o->obj_id == NULL) { - free(o); + TEE_Free(o); res = TEE_ERROR_OUT_OF_MEMORY; goto out; } @@ -155,8 +155,8 @@ TEE_Result tee_pobj_release(struct tee_pobj *obj) obj->refcnt--; if (obj->refcnt == 0) { TAILQ_REMOVE(&tee_pobjs, obj, link); - free(obj->obj_id); - free(obj); + TEE_Free(obj->obj_id); + TEE_Free(obj); } // mutex_unlock(&pobjs_mutex); @@ -178,7 +178,7 @@ TEE_Result tee_pobj_rename(struct tee_pobj *obj, void *obj_id, goto exit; } - new_obj_id = malloc(obj_id_len); + new_obj_id = TEE_Malloc(obj_id_len, TEE_MALLOC_FILL_ZERO); if (new_obj_id == NULL) { res = TEE_ERROR_OUT_OF_MEMORY; goto exit; @@ -186,13 +186,13 @@ TEE_Result tee_pobj_rename(struct tee_pobj *obj, void *obj_id, memcpy(new_obj_id, obj_id, obj_id_len); /* update internal data */ - free(obj->obj_id); + TEE_Free(obj->obj_id); obj->obj_id = new_obj_id; obj->obj_id_len = obj_id_len; new_obj_id = NULL; exit: // mutex_unlock(&pobjs_mutex); - free(new_obj_id); + TEE_Free(new_obj_id); return res; } diff --git a/tee/tee/tee_svc_cryp.c b/tee/tee/tee_svc_cryp.c index 610237bb..be24999f 100644 --- a/tee/tee/tee_svc_cryp.c +++ b/tee/tee/tee_svc_cryp.c @@ -1545,7 +1545,7 @@ TEE_Result utee_cryp_obj_populate(unsigned long obj, if (MUL_OVERFLOW(sizeof(TEE_Attribute), attr_count, &alloc_size)) return TEE_ERROR_OVERFLOW; - attrs = malloc(alloc_size); + attrs = TEE_Malloc(alloc_size, TEE_MALLOC_FILL_ZERO); if (!attrs) return TEE_ERROR_OUT_OF_MEMORY; @@ -1564,7 +1564,7 @@ TEE_Result utee_cryp_obj_populate(unsigned long obj, o->info.handleFlags |= TEE_HANDLE_FLAG_INITIALIZED; out: - free(attrs); + TEE_Free(attrs); return res; } @@ -1890,7 +1890,7 @@ static void cryp_state_free(struct user_ta_ctx *utc, struct tee_cryp_state *cs) assert(!cs->ctx); } - free(cs); + TEE_Free(cs); } static TEE_Result tee_svc_cryp_check_key_type(const struct tee_obj *o, diff --git a/tee_client/libteec/src/tee_client_api.c b/tee_client/libteec/src/tee_client_api.c index a485e16f..4922fa90 100644 --- a/tee_client/libteec/src/tee_client_api.c +++ b/tee_client/libteec/src/tee_client_api.c @@ -746,6 +746,7 @@ TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *ctx, TEEC_SharedMemory *shm) if (ctx->reg_mem) { shm->buffer = malloc(s); + // shm->buffer = pvPortMalloc(s); if (!shm->buffer) return TEEC_ERROR_OUT_OF_MEMORY; @@ -788,6 +789,7 @@ void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *shm) // if (shm->registered_fd >= 0) { if (shm->buffer_allocated) free(shm->buffer); + // vPortFree(shm->buffer); // close(shm->registered_fd); // } else // munmap(shm->buffer, shm->alloced_size);