KMU PSA persistent key generation

We want to use PSA crypto to generate a persistent key that can't be read out and use this for encryption/decryption.

We have of course tried the persistent_key_usage sample both with and without TF-M ITS. The problem for us is that when enabling TF-M ITS 40% of the available RAM for our target nRF54L10 is consumed. As an alternative CONFIG_TRUSTED_STORAGE could be used, but there are some reasons why we don't want to use this path.

As I interprete this documentation, it should be possible to use the KMU slots directly using PSA crypto API:
https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf54l/cryptography.html#ug-nrf54l-crypto-kmu-supported-key-types
By doing so we don't need the extra storage partitions etc needed for TF-M ITS and I would assume it would require less RAM.
But I can't get it to work. Have tried various config etc, but calling psa_generate_key() it returns -134 PSA_ERROR_NOT_SUPPORTED.

Here is my code:

#include <psa/crypto.h>
#include <cracen_psa_kmu.h>

static int crypto_test(void)
{
    psa_key_id_t keyId;
    psa_status_t status;
    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;

    status = psa_crypto_init();
    if (status != PSA_SUCCESS) {
        return status;
    }

    // Set the key as persistent
    psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
                             PSA_KEY_PERSISTENCE_DEFAULT,
                             PSA_KEY_LOCATION_CRACEN_KMU));

    // Set a fixed key ID
    psa_set_key_id(&attributes, PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(CRACEN_KMU_KEY_USAGE_SCHEME_PROTECTED, 2));

    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT);
    psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
    psa_set_key_bits(&attributes, 128);

    status = psa_generate_key(&attributes, &keyId);
    printf("psa_generate_key: %d\n", status);
    return status;
}


and config:
# Enable Trusted Firmware
CONFIG_TFM_PROFILE_TYPE_MINIMAL=y

CONFIG_NRF_SECURITY=y

CONFIG_MBEDTLS_PSA_CRYPTO_C=y
CONFIG_MBEDTLS_PSA_CRYPTO_STORAGE_C=y

CONFIG_PSA_WANT_GENERATE_RANDOM=y
CONFIG_PSA_WANT_KEY_TYPE_AES=y
CONFIG_PSA_WANT_ALG_CBC_NO_PADDING=y

CONFIG_PSA_CRYPTO_DRIVER_OBERON=n
CONFIG_PSA_CRYPTO_DRIVER_CRACEN=y

So am I missing something?

  • Hi Andreas,

    Some colleagues helped me look into it. There are a few issues that we need to address:

    • There is indeed a bug in NCS v2.9.0 that makes psa_cipher_encrypt() failed. It is fixed here with this PR: https://github.com/nrfconnect/sdk-nrf/pull/20199.

      You can patch NCS with that PR, or try NCS main branch right now. 

    • ALG_CBC_NO_PADDING requires that the plain text is a multiple of the AES block size, 16. Therefore, please ensure this.

    • There seems to be some issue with KMU slot 2 at the moment. We are looking into it.

      Meanwhile, please try some other slot, like 3 or 4.

    Below I also attached my tested sample. Remember that it only works with PR 20199 patched.

    By the way, if you don't mind sharing, our team would like to ask you about the reason you don't want to use Trusted Storage. We hope it is not also some RAM consumption issue, which can be a little strange.

    c339750_persistent_key_usage_modified_kmu.zip

    Hieu

  • Hi Hieu!
    Sorry for not coming back to you sooner - had some urgent tasks I needed to do.
    Thank you very much for the patch! With it I can get the KMU slots to work both with and without TF-M enabled.

    In our application we will just use one or two keys. We would like to use TF-M as long as the memory footprint isn't too large. However, this is what I'm facing right now:
    If I enable CONFIG_TFM_PROFILE_TYPE_MINIMAL the I get these numbers:

    [191/195] Linking C executable bin/tfm_s.axf
    Memory region         Used Size  Region Size  %age Used
               FLASH:       25660 B        26 KB     96.38%
                 RAM:        9332 B        32 KB     28.48%

    These could be OK for us. I.e. TF-M only uses ~10 KB of RAM and I think CONFIG_PM_PARTITION_SIZE_TFM_SRAM can adjust the dedicated RAM area so that it doesn't need to reserve the 32 KB it currently does.

    The problem I'm facing is when I'm enabling CONFIG_TFM_ITS_ENCRYPTED. This config doesn't work with CONFIG_TFM_PROFILE_TYPE_MINIMAL so then when compiling I get this footprint:

    [245/249] Linking C executable bin/tfm_s.axf
    Memory region         Used Size  Region Size  %age Used
               FLASH:       78096 B       254 KB     30.03%
                 RAM:       56744 B        76 KB     72.91%

    It also needs the extra NVM partitions for the trusted storage not listed here. 

    Am I missing some config to keep the footprint down here because I can't see how it would be worth wasting this much RAM/NVM just to be able to store some keys. Isn't the purpose of the KMU exactly to keep the keys securly stored but with the main difference that it's a HW block which cost no RAM/NVM?

    The remaining problem I see now is that if we want to use TF-M I still need to enable CONFIG_TFM_ITS_ENCRYPTED even if I use the KMU to store the key resulting in the big mem footprint.

    Kind regards

    /Andreas

Related