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?

Parents
  • Hi Andreas,

    I was trying to reproduce your issue with the Crypto: Persistent key storage sample. I did run into issues, but not the one you have.

    If I replace either the lifetime attribute, or the algorithm attribute, or both, with the ones you used, psa_cipher_encrypt() returns -135, PSA_ERROR_INVALID_ARGUMENT.

    The key generation itself works fine. As this overall still failed, I will continue looking into it, but can you double check your setup to see if the key generation is working?

    Hieu

  • Hi Hieu,

    If you use the persistent key storage example and build it for nrf54l15dk/nrf54l15/cpuapp/ns it will, by default, enable Trusted Firmware ITS through the CONFIG_TFM_ITS_ENCRYPTED. When this is enabled TF-M will use a lot of RAM and it will also add the extra partitions for TF-M secure storage. This is exactly what we want to avoid, so maybe you can use hello world app as a starting point instead (this is what I used). In this way we can make sure no other config is set.

    Since the nRF54Lxx includes the Key Management Unit HW we want to store the keys directly in this HW instead of wasting a lot of RAM and flash using a software implementation of securly storing the keys using TF-M ITS. According to the doc  below, as I read it, the way to do this is to use the PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION() with PSA_KEY_LOCATION_CRACEN_KMU when setting the lifetime by calling psa_set_key_lifetime(). As far as I understand from the same doc I also need to use PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT() when setting the key_id using psa_set_key_id():
    https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf54l/cryptography.html#programming_model_for_referencing_keys

    If I replace either the lifetime attribute, or the algorithm attribute, or both, with the ones you used, psa_cipher_encrypt() returns -135, PSA_ERROR_INVALID_ARGUMENT.

    I think when you don't use these arguments the generated keys will be stored in TF-M ITS (Internal Trusted Storage) and not KMU. I have no problem running the Persistent key storage example without any modifications, the problem is that the keys then are stored in the TF-M ITS and not KMU. The reason that you get PSA_ERROR_INVALID_ARGUMENT instead of PSA_ERROR_NOT_SUPPORTED could maybe be that the Persistent key storage example sets CONFIG_TFM_ITS_ENCRYPTED which I don't use.

    /Andreas

  • Hi Andreas,

    A colleague also points out that you are enabling TF-M for the nRF54L10, but I am not. I just built with the nrf54l15dk/nrf54l10/cpuapp target. That would explain the difference between your observation and mine.

    However, the problem is that TF-M isn't supported on the nRF54L10 yet. See this Security Feature Support matrix.

    Before we go further, can you proceed without TF-M for now?

    Also, while we understood that you are concern about NVM and RAM consumption of TF-M, could you share why? This is to see if there are any alternatives that can help. Of course, as TF-M isn't supported now, the point is a little moot.

    Hieu

Reply
  • Hi Andreas,

    A colleague also points out that you are enabling TF-M for the nRF54L10, but I am not. I just built with the nrf54l15dk/nrf54l10/cpuapp target. That would explain the difference between your observation and mine.

    However, the problem is that TF-M isn't supported on the nRF54L10 yet. See this Security Feature Support matrix.

    Before we go further, can you proceed without TF-M for now?

    Also, while we understood that you are concern about NVM and RAM consumption of TF-M, could you share why? This is to see if there are any alternatives that can help. Of course, as TF-M isn't supported now, the point is a little moot.

    Hieu

Children
  • Hi Hieu,

    ok, understod. I thought the only difference between nRF54L15 and nRF54L10 was NVM and RAM size according to the "nRF54L Series SoC options" in link below, so I'm a bit supprised that TF-M is supported only for nRF54L15:
    https://www.nordicsemi.com/Products/nRF54L15

    But let's focus on getting the generated keys stored in KMU with TF-M disabled if that helps.

    Also, while we understood that you are concern about NVM and RAM consumption of TF-M

    As I mentioned when I enabled TF-M the TF-M firmware consumed 40% of the RAM. This is RAM that we can't use for our own app as it is dedicated for TF-M.

    But I think we're getting a little out of topic. My question is how I get the things descripbed here to work:
    https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/app_dev/device_guides/nrf54l/cryptography.html
    I.e. can you provide a working config (with or without TF-M) that allows us to use the PSA crypto API to generate and store keys in a KMU slot?

    /Andreas

  • 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