PSA Non Secure Example

This example is to demonstrate how to use PSA library APIs to perform a Sign/Verify operations.

Pre-requisites

You need to build PSA-ALT library for TrustZone before compiling this application code.

Refer to Section 6.3 Platform Security Architecture.

Assigning PSA APIs

Assign function pointers for the secure world PSA APIs that you want to support.

psa_drv_se_key_management_t key_mgmt_drv;
psa_drv_se_asymmetric_t asymm_drv;

memset(&key_mgmt_drv, 0, sizeof(psa_drv_se_key_management_t));
memset(&asymm_drv, 0, sizeof(psa_drv_se_asymmetric_t));
key_mgmt_drv.p_generate             = &psa_alt_generate_key;
key_mgmt_drv.p_allocate             = &psa_alt_allocate_key;
key_mgmt_drv.p_export               = &psa_alt_export_key;
key_mgmt_drv.p_destroy              = &psa_alt_destroy_key;
key_mgmt_drv.p_import               = &psa_alt_import_key;
key_mgmt_drv.p_validate_slot_number = &psa_alt_validate_slot_number;

asymm_drv.p_sign    = &psa_alt_asymmetric_sign_digest;
asymm_drv.p_verify  = &psa_alt_asymmetric_verify_digest;
asymm_drv.p_encrypt = &psa_alt_asymmetric_encrypt;
asymm_drv.p_decrypt = &psa_alt_asymmetric_decrypt;

memset(&driver, 0, sizeof(driver));
driver.hal_version    = PSA_DRV_SE_HAL_VERSION;
driver.p_init         = &psa_alt_driver_init;
driver.key_management = &key_mgmt_drv;
driver.asymmetric     = &asymm_drv;

Generate an asymmetric key.

psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
psa_set_key_usage_flags(&attributes,
    PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT | PSA_KEY_USAGE_EXPORT | PSA_KEY_USAGE_SIGN_HASH |
        PSA_KEY_USAGE_VERIFY_HASH);
psa_set_key_algorithm(&attributes, alg);
psa_set_key_type(&attributes, PSA_KEY_TYPE_RSA_KEY_PAIR);
psa_set_key_bits(&attributes, key_bits);
psa_set_key_lifetime(&attributes, lifetime);
psa_set_key_id(&attributes, key_id);

LOG_I("Generating RSA-%d key", key_bits);

status = psa_generate_key(&attributes, &key_handle);

Perform Sign-Verify operation with the key.

uint8_t hash[32]       = {1};
size_t hashLen         = sizeof(hash);
uint8_t signature[256] = {0};
size_t sigLen          = sizeof(signature);

status = psa_sign_hash(
    key_handle, PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256), hash, hashLen, signature, sizeof(signature), &sigLen);
if (status != 0) {
    LOG_E("Signing failed");
    goto cleanup;
}
else {
    LOG_I("Signing success");
}

status = psa_verify_hash(key_handle, PSA_ALG_RSA_PKCS1V15_SIGN(PSA_ALG_SHA_256), hash, hashLen, signature, sigLen);
if (status != 0) {
    LOG_E("Verification failed");
    goto cleanup;
}
else {
    LOG_I("Verification success");
}

Building Example

This example running in normal world should link with the secure world library (PSA) so that definition for veneer table APIs can be found. Build the normal world example with the following CMake configurations:

  • Host=lpcxpresso55s_ns

  • HostCrypto=MBEDCRYPTO

  • RTOS=Default

  • SMCOM=T1oI2C

  • PROJECT=psa_nonsecure