Skip to main content

Initialize NanoCrypto

This section describes how to initialize the NanoCrypto library with default settings.

To add NanoCrypto functions to an application, the library must first be initialized. To initialize with default settings, use this API (declared in ${MSS_SRC_PKG}/src/common/mocana.h):

MOC_EXTERN MSTATUS MOCANA_initMocana(void);

When an application launches, it calls the initialize method, and right before it exits, it calls the appropriate free function. To return NanoCrypto to an uninitialized state, your application can call the MOCANA_freeMocana method.

MOCANA_freeMocana();

Random number generator

NanoCrypto contains a global RNG and also allows for the ability to create local randomContext objects. The global random is created during the call to MOCANA_initMocana or MOCANA_initMocanaStaticMemory. During these calls, NanoCrypto builds and seeds a random object called g_pRandomContext. This object is usable anywhere a randomContext is required. The global random uses CTR DRBG algorithm by default using the AES block cipher.

To create a local randomContext object, use the API CRYPTO_INTERFACE_RANDOM_acquireContextEx. This local object may be the same or a different choice of RNG algorithm from that of the global RNG. For more information on this API, see the Crypto Interface random number generation guide, or refer to the example code located here: ${MSS_SRC_PKG}/src/crypto_interface/example/crypto_interface_random_example.c

Random seed

A random object is only as good as its seed. NanoCrypto contains an "autoseed" function that collects bits based on what is available on the system. This function is called by MOCANA_initMocana. However, you may want your application to provide its own seeding. For this scenario, refer to NanoCrypto external entropy injection.

Static memory

When NanoCrypto needs to allocate memory, it calls MOC_MALLOC, which in turn calls system malloc or some other system/OS memory management APIs. Alternatively, you can configure NanoCrypto to use only the caller-supplied static buffer. If you do, NanoCrypto does not make any system malloc/free calls to obtain and free memory. Instead, it uses internal memory management APIs against the supplied static buffer pool.

In addition, to reduce the pool fragmentation, you can configure the static memory buffer into partitions of small, medium, and large sized pools. This means small, medium, and large sized allocations will always be attempted first in the appropriate sized pool. The sizes of the pools and what constitutes a small, medium, or large allocation are build-time configurable. TrustCore SDK also provides a memory profiling tool you can use to derive an optimal pool configuration for your application.

To use the static memory feature, first, make sure NanoCrypto is built using the __ENABLE_MOCANA_MEM_PART__ build flag. Second, invoke the method MOCANA_initMocanaStaticMemory (declared in ${MSS_SRC_PKG}/src/common/mocana.h) instead of MOCANA_initMocana. This API takes in the application-provided static memory buffer to use for memory allocations.

ubyte pMemBuffer[65536];
status = MOCANA_initMocanaStaticMemory (pMemBuffer, sizeof (pMemBuffer));

Thereafter, any time NanoCrypto allocates memory, it invokes the internal memory management functions to use space from the buffer pMemBuffer. If this manager runs out of space (i.e., there are no more contiguous memory blocks to allocate in the available pool), the NanoCrypto library returns an error.

Estimate memory buffer size requirements

There are two ways to estimate memory buffer size requirements:

1. Build and run a test application with the __ENABLE_MOCANA_DEBUG_MEMORY__ build flag

The first option is to build an application that uses NanoCrypto (the build of the source files from the ${MSS_SRC_PKG}/src directory) with the __ENABLE_MOCANA_DEBUG_MEMORY__ build flag. This tracks all memory allocations and frees that the application and NanoCrypto make when using NanoCrypto allocation APIs (MOC_MALLOC, MOC_CALLOC, MOC_FREE, etc.).

In your application, after calling MOCANA_freeMocana(), invoke DBG_DUMP (found in ${MSS_SRC_PKG}/src/memory_debug.h). For example:

MSTATUS status;

status = MOCANA_initMocana();
...
MOCANA_freeMocana();

DBG_DUMP

DBG_DUMP prints a memory report. This memory report includes the maximum amount of memory used at a single point (Memory high water mark), the total cumulative amount of memory allocated (Total memory allocated), and the total number of allocation calls made (Total calls to malloc). The report also tracks allocations which have not been freed, or if invalid memory space has been accessed.

MEMORY LEAKS FOUND =============================
.................. None!
MEMORY PAD DAMAGE FOUND ========================
.................. None!
BAD FREES FOUND ================================
.................. None!
================================================
Memory high water mark: 18068
Total memory allocated: 27828
Total calls to malloc: 17

This report gives a reasonable estimate of buffer size requirements. However, due to fragmentation, the actual required size is around 20-40% bigger. Once you have this report, you can run the test application with static memory, tweaking the buffer size until the application runs without memory errors.

2. Use the external Pool Size Selection Tool

The second option to determine the size of the buffer needed is to use the external Pool Size Selection Tool. This tool can also be used to determine if it is beneficial to enable the small, medium, and large partitions. These partitions can be enabled via the build flag __ENABLE_MOCANA_MEM_PART_MULTI_POOLS__.

See the Static Memory Partition Manager Guide for how to use the Pool Size Selection Tool, and how to configure the small, large, and medium sized memory pool partitions.