Stack Crash when used psa_ps_set (not */ns build) to store a certificate

Product: nRF54L15, SDK: V2.9.0

Application: Matter + BLE multi-protocol

Hi, 

we want to store X509 certificates in  secure storage.  I went went through Nordic supplied materials, Dev Zone and tried an implementation without success.

Material went through:

  1. https://docs.nordicsemi.com/bundle/ncs-2.9.1/page/nrf/app_dev/device_guides/nrf54l/cryptography.html#ug-nrf54l-crypto-configuration
  2. https://devzone.nordicsemi.com/nordic/nordic-blog/b/blog/posts/persistent-storage-of-keys-and-data-using-the-nrf-connect-sdk?utm_source=chatgpt.com
    1. The above one is good one, and it would help more if there would be sample application. The one provided is not easy one.
  3. Sample example: Hardware Unique Key, psa related etc.
  4. Nordic Dev Zone past tickets but can not find much help.

 psa_ps_set() fails for PSA protected storage without TF-M 

I added the below code in the matter + BLE application which was based on Nordic's Matter door lock example. I started with certificates initially, the stack crash occurred and then switch to the below simple example, which apparently someone else also tried.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
psa_status_t status;
status = psa_crypto_init();
if (status != PSA_SUCCESS)
{
printk("Issue with initializing crypto engine\n");
}
else
{
printk(" Crypto Initialized \n");
}
MtiCryptoKeysInit(); // see the code below attachement. This one generates HUK and MEKE
int rc = settings_subsys_init(); // added this based on a previous Nordic ticket, I don't think it is needed. Matter enables this by default
if (rc) {
printk("settings subsys initialization: fail (err %d)\n", rc);
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

I traced the code and found that the stack crash occurs when  cracen_key_derivation_cmac_ctr_generate_K_0(operation) is called from /opt/nordic/ncs/v2.9.0/nrf/subsys/nrf_security/src/drivers/cracen/cracenpsa/src/key_derivation.c, line no 1134. I have added the printk's and I see  the  printk("In S7:T32 state=%d->",operation->state * 100) getting printed. I have another printk and it does not get executed.

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
printk("In S7:T3, State=%d ->", operation->state);
if (IS_ENABLED(PSA_NEED_CRACEN_SP800_108_COUNTER_CMAC) &&
(operation->alg == PSA_ALG_SP800_108_COUNTER_CMAC)) {
if (operation->state == CRACEN_KD_STATE_CMAC_CTR_KEY_LOADED ||
operation->state == CRACEN_KD_STATE_CMAC_CTR_INPUT_LABEL ||
operation->state == CRACEN_KD_STATE_CMAC_CTR_INPUT_CONTEXT ||
operation->state == CRACEN_KD_STATE_CMAC_CTR_OUTPUT) { printk("In S7:T31 ->");
if (operation->state != CRACEN_KD_STATE_CMAC_CTR_OUTPUT) { printk("In S7:T32 ->");
operation->state = CRACEN_KD_STATE_CMAC_CTR_OUTPUT; printk("In S7:T32 state=%d->",operation->state * 100);
psa_status_t status =
cracen_key_derivation_cmac_ctr_generate_K_0(operation);
if (status != PSA_SUCCESS) {
return status;
}
} printk("In S7:T33 ->");
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

The prj.conf settings are:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CONFIG_NCS_SAMPLE_MATTER_PERSISTENT_STORAGE=y
CONFIG_NCS_SAMPLE_MATTER_SETTINGS_STORAGE_BACKEND=y
CONFIG_NCS_SAMPLE_MATTER_SECURE_STORAGE_BACKEND=y
CONFIG_TRUSTED_STORAGE_BACKEND_AEAD_MAX_DATA_SIZE=2048
CONFIG_SETTINGS=y
CONFIG_ZMS=y
CONFIG_NVS=n
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NRF_SECURITY=y
CONFIG_PSA_CRYPTO_DRIVER_CRACEN=y
CONFIG_PSA_CRYPTO_DRIVER_OBERON=n
CONFIG_MBEDTLS_PSA_CRYPTO_C=y
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

 I have also added the code to generate HUK and MKEK - below is  the code. The below functions calls the same function and completes successfully. 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
psa_status_t derive_key()
{
uint8_t key_out[PSA_BITS_TO_BYTES(256)];
psa_key_id_t key_id;
static psa_key_id_t key_id_out;
#define ENCRYPT_ALG PSA_ALG_GCM
psa_status_t status;
int err;
psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
uint8_t key_label[] = "HUK derivation sample label";
LOG_INF("Generating MKEK key");
/* Set the key attributes for the storage key */
psa_set_key_usage_flags(&attributes,
(PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT));
psa_set_key_algorithm(&attributes, ENCRYPT_ALG);
psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
psa_set_key_bits(&attributes, 256);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  1. The purpose is to store X509 certificates securely. Is there  a better method and an sample solution available.
  2. If what I am pursuing is the correct method, then  please advise a  solution to overcome the stack crash. I feel that I am missing something, since the same functions are used/working  when I try to derive a key based on HUK.
Parents
  • Hi,

    Did you get error "ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0" when using your simple example?

    Best regards,
    Dejan

Reply
  • Hi,

    Did you get error "ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0" when using your simple example?

    Best regards,
    Dejan

Children
  • Hi Dejan,  Yes. Please see below:

    --------

    E: Stack overflow (context area not valid)
    E: r0/a1: 0xaaaaaaaa r1/a2: 0xaaaaaaaa r2/a3: 0xaaaaaaaa
    E: r3/a4: 0xaaaaaaaa r12/ip: 0x00042f78 r14/lr: 0x69000200
    E: xpsr: 0x2002fa00
    E: Faulting instruction address (r15/pc): 0xaaaaaaaa
    E: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0
    E: Current thread: 0x20012bf0 (main)
    E: Halting system

    ----

  • Hi,

    Can you provide your build command and complete application log (for your simple example)?

    Best regards,
    Dejan

  • The build was done using VS code.   This is a simple example and we used nRF54L15DK. 

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    ### prj.conf
    #
    # Copyright (c) 2024 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    # The Zephyr CMSIS emulation assumes that ticks are ms, currently
    CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000
    CONFIG_MAIN_STACK_SIZE=4096
    CONFIG_HEAP_MEM_POOL_SIZE=4096
    # Enable logging
    CONFIG_CONSOLE=y
    CONFIG_LOG=y
    # Enable nordic security backend and PSA APIs
    CONFIG_NRF_SECURITY=y
    CONFIG_MBEDTLS_PSA_CRYPTO_C=y
    CONFIG_PSA_CRYPTO_DRIVER_CRACEN=y
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    // Main.c
    /*
    * Copyright (c) 2021 Nordic Semiconductor ASA
    *
    * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    */
    #include <zephyr/kernel.h>
    #include <zephyr/logging/log.h>
    #include <string.h>
    #include <stdio.h>
    #include <psa/crypto.h>
    #include <psa/crypto_extra.h>
    #include <zephyr/sys/crc.h>
    #include <cracen_psa_key_ids.h>
    #include <cracen_psa_kmu.h>
    #include <hw_unique_key.h>
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Build logs:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    Building psa_ps_set
    west build --build-dir /Users/subumuthu/Nordic/psa_ps_set/build /Users/subumuthu/Nordic/psa_ps_set --pristine --board nrf54l15dk/nrf54l15/cpuapp --sysbuild -- -DNCS_TOOLCHAIN_VERSION=NONE -DBOARD_ROOT=/Users/subumuthu/Nordic/psa_ps_set
    -- west build: generating a build system
    Loading Zephyr module(s) (Zephyr base): sysbuild_default
    -- Found Python3: /opt/nordic/ncs/toolchains/b8efef2ad5/opt/python@3.12/bin/python3.12 (found suitable version "3.12.4", minimum required is "3.8") found components: Interpreter
    -- Cache files will be written to: /Users/subumuthu/Library/Caches/zephyr
    -- Found west (found suitable version "1.2.0", minimum required is "0.14.0")
    -- Board: nrf54l15dk, qualifiers: nrf54l15/cpuapp
    Parsing /opt/nordic/ncs/v2.9.1/zephyr/share/sysbuild/Kconfig
    Loaded configuration '/Users/subumuthu/Nordic/psa_ps_set/build/_sysbuild/empty.conf'
    Merged configuration '/Users/subumuthu/Nordic/psa_ps_set/build/_sysbuild/empty.conf'
    Configuration saved to '/Users/subumuthu/Nordic/psa_ps_set/build/zephyr/.config'
    Kconfig header saved to '/Users/subumuthu/Nordic/psa_ps_set/build/_sysbuild/autoconf.h'
    --
    ********************************
    * Running CMake for psa_ps_set *
    ********************************
    Loading Zephyr default modules (Zephyr base).
    -- Application: /Users/subumuthu/Nordic/psa_ps_set
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    UART Logs - stack crash below:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    *** Booting nRF Connect SDK v2.9.1-60d0d6c8d42d ***
    *** Using Zephyr OS v3.7.99-ca954a6216c9 ***
    Generate HW unique Key
    Writing random keys to KMUSuccess!Derive a Key
    Generating MKEK key
    Generating MKEK ------->Success in MKEK gen Imported the key
    ----------- Store somethign using psa_set----------
    [00:00:00.436,094] .[1;31m<err> os: ***** USAGE FAULT *****.[0m
    [00:00:00.436,098] .[1;31m<err> os: Stack overflow (context area not valid).[0m
    [00:00:00.436,109] .[1;31m<err> os: r0/a1: 0x00000002 r1/a2: 0x00000000 r2/a3: 0x00000000.[0m
    [00:00:00.436,116] .[1;31m<err> os: r3/a4: 0x200045e8 r12/ip: 0x00000000 r14/lr: 0x0000a4c5.[0m
    [00:00:00.436,121] .[1;31m<err> os: xpsr: 0x09000200.[0m
    [00:00:00.436,125] .[1;31m<err> os: Faulting instruction address (r15/pc): 0x0000435c.[0m
    [00:00:00.436,144] .[1;31m<err> os: >>> ZEPHYR FATAL ERROR 2: Stack overflow on CPU 0.[0m
    [00:00:00.436,159] .[1;31m<err> os: Current thread: 0x200008d0 (unknown).[0m
    [00:00:00.521,288] .[1;31m<err> os: Halting system.[0m
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    This is a simple sample program to verify the working for psa_ps_set(). The HUK and MKEK key derivations were added to confirm. 

    Thanks.

    Subu

  • Hi Subu,

    Thank you for sharing additional details.

    Can you try to add CONFIG_THREAD_NAME to your prj.conf file for finding out in which thread stack overflow occurred? Afterwards, you could try to increase stack size for that particular thread.

    Best regards,
    Dejan