psa_generate_key into KMU fails on nRF54L15 (NCS 2.9.1) with PSA_ERROR_NOT_SUPPORTED

Hi,
 I’m trying to provision a P‑256 key pair into the KMU at runtime on an nRF54L15 (SDK v2.9.1) but psa_generate_key consistently returns PSA_ERROR_NOT_SUPPORTED, even when I fall back to local storage.



  Environment

  - SoC: nRF54L15 (DK)
  - nRF Connect SDK: v2.9.1

CONFIG_NRF_SECURITY=y
CONFIG_MBEDTLS_PSA_CRYPTO_C=y
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_X509_LIBRARY=y
CONFIG_MBEDTLS_SSL_CLI_C=y
CONFIG_PSA_WANT_ECC_SECP_R1_256=y
CONFIG_PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY=y
CONFIG_PSA_WANT_ALG_ECDSA=y
CONFIG_PSA_WANT_ALG_SHA_256=y
CONFIG_PSA_WANT_KEY_TYPE_AES=y
CONFIG_PSA_WANT_ALG_GCM=y
CONFIG_MBEDTLS_ECP_C=y
CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y
CONFIG_MBEDTLS_ECDH_C=y
CONFIG_MBEDTLS_ECDSA_C=y
CONFIG_MBEDTLS_AES_C=y
CONFIG_MBEDTLS_GCM_C=y
CONFIG_MBEDTLS_SHA256_C=y
CONFIG_MBEDTLS_CTR_DRBG_C=y
CONFIG_MBEDTLS_ENTROPY_C=y
CONFIG_MBEDTLS_PK_C=y
CONFIG_MBEDTLS_X509_CRT_PARSE_C=y
CONFIG_MBEDTLS_PK_PARSE_C=y
CONFIG_MBEDTLS_X509_USE_C=y
CONFIG_TLS_CREDENTIALS=y
CONFIG_MBEDTLS_TLS_LIBRARY=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_PEM_PARSE_C=y
CONFIG_MBEDTLS_X509_REMOVE_INFO=y
CONFIG_MBEDTLS_SSL_KEEP_PEER_CERTIFICATE=n
CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y
CONFIG_MBEDTLS_RSA_C=n
CONFIG_PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY=n
CONFIG_PSA_WANT_ALG_RSA_PKCS1V15_SIGN=n
CONFIG_MBEDTLS_SHA1_C=n
CONFIG_PSA_WANT_ALG_SHA_1=n

What I’m doing

  static int ensure_kmu_p256_key(void)
  {
      psa_status_t status = psa_crypto_init();
      psa_key_id_t key_id = mbedtls_svc_key_id_make(
          0,
          PSA_KEY_HANDLE_FROM_CRACEN_KMU_SLOT(
              CRACEN_KMU_KEY_USAGE_SCHEME_RAW, 200)); /* non-reserved slot */

      psa_key_handle_t handle = PSA_KEY_ID_NULL;
      status = psa_open_key(key_id, &handle);
      /* ... if it exists, exit early ... */

      psa_key_attributes_t attrs = PSA_KEY_ATTRIBUTES_INIT;
      psa_set_key_type(&attrs, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1));
      psa_set_key_bits(&attrs, 256);
      psa_set_key_usage_flags(&attrs, PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_EXPORT);
      psa_set_key_algorithm(&attrs, PSA_ALG_ECDSA(PSA_ALG_ANY_HASH));

      const struct lifetime_option lifetimes[] = {
          {
              PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
                  (psa_key_persistence_t)CRACEN_KEY_PERSISTENCE_REVOKABLE,
                  PSA_KEY_LOCATION_CRACEN_KMU),
              "KMU"
          },
          {
              PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
                  PSA_KEY_PERSISTENCE_DEFAULT,
                  PSA_KEY_LOCATION_LOCAL_STORAGE),
              "local storage"
          },
      };

      for (...) {
          psa_set_key_lifetime(&attrs, lifetimes[i].lifetime);
          psa_set_key_id(&attrs,
              lifetimes[i].lifetime == KMU lifetime ? key_id : PSA_KEY_ID_USER_MIN + 1);

          status = psa_generate_key(&attrs, &key_id);
          if (status == PSA_SUCCESS) {
              LOG_INF("Generated P-256 key in %s", lifetimes[i].name);
              return 0;
          }
          LOG_WRN("Key lifetime %s not supported", lifetimes[i].name);
      }

      LOG_ERR("P-256 key generation not supported by available PSA backends");
      return -ENOTSUP;
  }

  Runtime output

  <wrn> Key lifetime KMU not supported
  <wrn> Key lifetime local storage not supported
  <err> P-256 key generation not supported by available PSA backends
  <err> Failed to ensure KMU key: -134

I’ve tried az bunch of things like
RAW and ENCRYPTED
Different slot indices
Falling back to local storage (PSA_KEY_LOCATION_LOCAL_STORAGE)

Nothing works, so Istart to think I'm missing something obvious:
Is runtime psa_generate_key() into KMU actually supported on nRF54L15 in NCS 2.9.1, or is external provisioning (e.g., west ncs-provision or psa_import_key) the only supported path today?
Thanks


Related