8 Integration With MPLAB® X IDE
TrustZone® Project Setup Steps
The PSA Crypto library must be integrated into the Secure project of a TrustZone application.
Step 1: Create TrustZone® Project
- Create a new project in MPLAB X: File→New Project→Microchip Embedded→New Application Project.
- Select PIC32CM5112SG00100.
- Use MPLAB Code Configurator (MCC) to configure peripherals into the Secure or Non-Secure projects, as needed. Refer to the MCC guide to generate code for secure/non-secure peripherals. For more information, see TrustZone Applications.
- Use MCC for memory partitioning based on your application requirements to allocate Secure , Non-Secure Flash and RAM areas as explained in memory configuration section above. Refer to the MCC for Flash and SRAM Partitioning section.
Step 2: Add Library to Secure Project
- Copy the library package built in the Building the PSA Crypto Library From Source Code section to the project directory.
- Right-click Secure project and go to Properties.
- Navigate to Project→Libraries→Add Library/Object file.
- Add the library paths for these
libraries:
libtfpsacrypto.a,libhsmlite04777-pic32cm.a.
Step 3: Configure Include Paths
- In Secure Project Properties→XC32 (Global Options)→xc32-gcc→Preprocessing and messages.
- Add the include directories generated in
Building the PSA
Crypto Library From Source Code:
pic32cmsg-psa-crypto-build\hsmlite\includeand directories insidepic32cmsg-psa-crypto-build\include.
Step 4: Initialize PSA Crypto Subsystem
In the Secure project main function, add the PSA initialization as shown below. Note that this is only a reference skeleton code structure. Refer to the Demo Application for PSA section for the implementation.
PSA
Init
typedef int32_t psa_status_t;
/* Initialize all modules */
SYS_Initialize ( NULL );
/* Initialize the PSA Crypto subsystem (must be done before NS handoff) */
psa_status_t psa_status = psa_crypto_init();
if (psa_status != PSA_SUCCESS)
{
/* PSA init failed - Error handler to be implmented here if needed */
}
/* Set the non-secure Main stack and call the reset handler*/Step 5: Create Veneer Functions
Design veneer functions based on your application’s specific cryptographic requirements.
Only expose the PSA operations that your Non-Secure application actually needs:
// nonsecure_entry.c(Secure project) #include "psa/crypto.h" typedef int32_t psa_status_t; /* Veneer function for RNG if needed by NS Application*/ psa_status_t __attribute__((cmse_nonsecure_entry)) secure_Crypto_Rng_Psa(const secure_Crypto_Rng_Psa_args_t *args) { psa_status_t status = PSA_ERROR_INVALID_ARGUMENT; /* Validate that a pointed-to object resides in the Non-Secure memory. Validate that a memory region resides entirely in the Non-Secure memory. */ status = psa_generate_random(args->p_output, (size_t)args->outputSize); /* Add a handler here in case of failure or return the error as needed */ return status; } /* Veneer function for SHA if needed by the NS Application - This is for reference only and not the full implementation */ __attribute__((cmse_nonsecure_entry)) psa_status_t nsc_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) { return psa_hash_compute(alg, input, input_length, hash, hash_size, hash_length); } // Add additional veneer functions as needed for your application
Step 6: Non-Secure Application
In the Non-Secure project, call the veneer functions:
// main.c (Non-Secure project) #include <stdint.h> #include <stddef.h> //Parameter struct for generating a random number in PSA typedef struct { uint8_t *p_output; uint32_t outputSize; } secure_Crypto_Rng_Psa_args_t; // PSA status type typedef int32_t psa_status_t; typedef uint32_t psa_algorithm_t; #define PSA_SUCCESS ((psa_status_t)0) #define PSA_ALG_SHA_256 ((psa_algorithm_t)0x02000009) #define OUTPUT_SIZE (12U) // Veneer function declarations extern psa_status_t secure_Crypto_Rng_Psa(const secure_Crypto_Rng_Psa_args_t *args); extern psa_status_t nsc_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); int main(void) { psa_status_t status; // Generate random bytes uint8_t random_data[32]; secure_Crypto_Rng_Psa_args_t args; args.p_output = random_data; args.outputSize = OUTPUT_SIZE; return (psa_status_t)secure_Crypto_Rng_Psa(&args); if (status != PSA_SUCCESS) { // Handle error } // Compute SHA-256 hash const uint8_t message[] = "Hello, PSA Crypto!"; uint8_t hash[32]; size_t hash_length; status = nsc_psa_hash_compute(PSA_ALG_SHA_256, message, sizeof(message) - 1, hash, sizeof(hash), &hash_length); if (status != PSA_SUCCESS) { // Handle error } while(1) { // Application main loop } }
