PSA Crypto (key derivation) fault on NRF54L15 when called from BLE callbacks

Dear Nordic Team,

I have to use PSA Crypto key derivation in my NRF54L15 firmware during BLE communication with BLE Central, however, I am experiencing a problem when I am trying to call key derivation from any of Bluetooth callbacks - the call to  simply resets the device with USAGE FAULT.  I have tried to wrap it into a worker call, however, it didn't help. 

Here is the test function, which works fine when it is called from the main() loop, however, once I put it into any BLE callback (e.g. characteristic write callback or even connection state callback, it results in immediate fault. I have done some debugging and it seems that the fault occurs/takes place somewhere inside psa_key_derivation_setup(&operation, alg) call. 

void test_psa_key_derivation_setup_impl(void)
{
    LOG_INF("Starting psa_key_derivation_setup test...");

    psa_status_t status;

    psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT;
    psa_algorithm_t alg = PSA_ALG_HKDF(PSA_ALG_SHA_256);
    psa_key_derivation_operation_t operation = PSA_KEY_DERIVATION_OPERATION_INIT;

    // Initialize PSA Crypto if needed

    status = psa_crypto_init();

    if (status != PSA_SUCCESS) {
        LOG_ERR("Failed to initialize PSA crypto for test");
        return;
    }
   
    // Get current auth key
    uint8_t auth_key[AUTH_KEY_SIZE];
    int err = flash_storage_get_auth_key_from_memory(auth_key);
    if (err) {
        LOG_ERR("Failed to get auth key for test: %d", err);
        return;
    }
   
    // Generate random nonces for testing
    uint8_t nonce1[NONCE_SIZE];
    uint8_t nonce2[NONCE_SIZE];
   
    // Use simple pseudo-random generation for testing
    for (int i = 0; i < NONCE_SIZE; i++) {
        nonce1[i] = (uint8_t)(k_uptime_get_32() + i) ^ 0xAA;
        nonce2[i] = (uint8_t)(k_uptime_get_32() + i + 100) ^ 0x55;
    }
   

    psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DERIVE);
    psa_set_key_algorithm(&attributes, alg);
    psa_set_key_type(&attributes, PSA_KEY_TYPE_DERIVE);

   
    psa_reset_key_attributes(&attributes);

    // Now test the actual psa_key_derivation_setup call
    LOG_INF("Calling psa_key_derivation_setup...");
   
    status = psa_key_derivation_setup(&operation, alg);
   
    if (status != PSA_SUCCESS) {
        LOG_ERR("psa_key_derivation_setup FAILED with status: %d", status);
        return;
    } else
    {
        LOG_INF("psa_key_derivation_setup SUCCESS!");
    }
   

        // Combine nonces for salt
       uint8_t salt[NONCE_SIZE + NONCE_SIZE];
       memcpy(salt, nonce1, NONCE_SIZE);
       memcpy(salt + NONCE_SIZE, nonce2, NONCE_SIZE);

       // Set salt
       status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_SALT,
                                        salt, sizeof(salt));

    if (status != PSA_SUCCESS)
    {
       LOG_ERR("PSA HKDF salt input failed");
       psa_key_derivation_abort(&operation);
       return;
    }
 
      // Set secret (auth key)
     status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_SECRET,
                                    auth_key, AUTH_KEY_SIZE);


    if (status != PSA_SUCCESS) {
      LOG_ERR("PSA HKDF secret input failed: %d", status);
      psa_key_derivation_abort(&operation);
      return;
    }

 // Set info
 const char *info = "session_key";
 status = psa_key_derivation_input_bytes(&operation, PSA_KEY_DERIVATION_INPUT_INFO,
                                        (const uint8_t *)info, strlen(info));
 if (status != PSA_SUCCESS)
 {
     LOG_ERR("PSA HKDF info input failed: %d", status);
     psa_key_derivation_abort(&operation);
     return;
 }

 // Derive session key
 uint8_t session_key[SESSION_KEY_SIZE];

 status = psa_key_derivation_output_bytes(&operation, session_key, SESSION_KEY_SIZE);
 
 if (status != PSA_SUCCESS)
 {
     LOG_ERR("PSA HKDF output failed: %d", status);
     psa_key_derivation_abort(&operation);
     return;
 }

 
    LOG_INF("psa_key_derivation_setup test completed");

    LOG_INF("Session key: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
            session_key[0], session_key[1], session_key[2], session_key[3], session_key[4], session_key[5], session_key[6], session_key[7],
            session_key[8], session_key[9], session_key[10], session_key[11], session_key[12], session_key[13], session_key[14], session_key[15]);

    psa_key_derivation_abort(&operation);    
}
My K Configuration is as following:
CONFIG_NRF_SECURITY=y
CONFIG_PSA_CRYPTO_DRIVER_CRACEN=y
CONFIG_MBEDTLS_PSA_CRYPTO_C=y

CONFIG_PSA_WANT_ALG_CCM=y
CONFIG_PSA_WANT_ALG_HKDF=y
CONFIG_PSA_WANT_ALG_SHA_256=y
CONFIG_PSA_WANT_ALG_HMAC=y
CONFIG_PSA_WANT_KEY_TYPE_AES=y
CONFIG_PSA_WANT_KEY_TYPE_RAW_DATA=y
Please help! Thanks in advance.
Related