NCS 3.4.0: Cannot disable mbed TLS / TF-M Crypto partition with modem-offloaded sockets

Summary: CONFIG_MBEDTLS is force-enabled and won't compile without PSA_CRYPTO, costing ~31 KB of secure RAM for unused functionality

I've just migrated my project from v.3.3.1 to v3.4.0

Since our application uses modem-offloaded TLS exclusively, we want to build with TF-M providing only the Platform partition (CONFIG_TFM_PARTITION_CRYPTO=n, ITS/PS/Attestation also off) to minimize secure RAM/flash. In NCS 3.4.0 this appears impossible: CONFIG_MBEDTLS is force-enabled and then fails to compile unless CONFIG_PSA_CRYPTO=y, which in turn unavoidably re-selects CONFIG_TFM_PARTITION_CRYPTO. The net cost we measured is ~31 KB(!!!!) of additional secure SRAM (TF-M RAM goes from 6,132 B with Crypto off to 37,180 B with Crypto+Platform on) for a service our application never calls.

An explicit # CONFIG_MBEDTLS is not set in our conf fragment is silently ignored: because MBEDTLS's prompt is conditional (bool "..." if !MBEDTLS_PROMPTLESS), the user assignment doesn't take effect against the imply. We only get the warning MBEDTLS was assigned the value 'n' but got the value 'y' and the build proceeds with CONFIG_MBEDTLS=y. (Disabling PSA_CRYPTO the same way does work, since its prompt is unconditional.)

With MBEDTLS=y and PSA_CRYPTO=n, compilation fails.

Is there a supported way to build BUILD_WITH_TFM=y with the Zephyr NS app while keeping CONFIG_MBEDTLS=n (or at least TFM_PARTITION_CRYPTO=n) when all TLS is modem-offloaded?

If not currently supported, can the imply MBEDTLS if !TFM_USE_NS_APP be relaxed (e.g., made overridable, or gated on something like NET_SOCKETS_OFFLOAD/an opt-out symbol) in a future release?

Parents
  • Hi again Regan, 
    Could you send us a minimal project so we can have a look at your configurations and test here ? 
    Have you used CONFIG_TFM_PROFILE_TYPE_MINIMAL=y ? 
    It's also suggested that you look at the modem_shell sample which also uses socket offloading. 
    Here is the memory footprint in the sample: 

    [140/142] Linking C executable bin/tfm_s.axf
    Memory region         Used Size  Region Size  %age Used
               FLASH:       32144 B        32 KB     98.10%
                 RAM:        6152 B        32 KB     18.77%

  • Here are my current build footprint stats:

    [90/92] Linking C executable bin\tfm_s.axf
    Memory region         Used Size  Region Size  %age Used
               FLASH:       23128 B      56832 B     40.70%
                 RAM:        6132 B        16 KB     37.43%
    [25/476] Performing install step for 'tfm'
    -- Install configuration: "MinSizeRel"
    ----- Installing platform NS -----
    [475/476] Linking C executable zephyr\zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:      405960 B     433978 B     93.54%
                 RAM:      221344 B     227968 B     97.09%
            IDT_LIST:           0 B        32 KB      0.00%
    [6/221] Generating include/generated/zephyr/version.h
    -- Zephyr version: 4.4.0 (C:/ncs/v3.4.0/zephyr), build: ncs-v3.4.0
    [221/221] Linking C executable zephyr\zephyr.elf
    Memory region         Used Size  Region Size  %age Used
               FLASH:       28048 B        40 KB     68.48%
                 RAM:       16440 B        88 KB     18.24%
            IDT_LIST:           0 B        32 KB      0.00%

    I have been able to get my project to build (and happily run) with a hack, using CMake to strip MBEDTLS out and replace it with an empty stub, but it's an ugly solution. It's my understanding the modem-offloaded TLS is a requirement for nRFCloud connection and that's indeed what my project can still do (in v3.3.1 and 3.4.0)

    If it helps your team, I got an AI agent to summarise the problem and temporary solution:

    "The forced-on mbed TLS 4.x library then fails to compile with PSA_CRYPTO off (mbedtls_error_pair_t only exists under MBEDTLS_PSA_CRYPTO_CLIENT, which is "def_bool y depends on PSA_CRYPTO"). Kconfig-level workarounds are dead ends in NCS 3.4.0 (MBEDTLS_CUSTOM is blocked by an nrf_security CMake FATAL_ERROR; select of MBEDTLS_PSA_CRYPTO_CLIENT is a hard Zephyr Kconfig error). Instead, MYPROJECT_STRIP_MBEDTLS (project Kconfig + CMakeLists.txt) stubs out the unused mbed TLS library target at the CMake level so PSA_CRYPTO and TFM_PARTITION_CRYPTO can stay off (saves ~24 KiB secure SRAM + ~33 KB TF-M flash vs. letting the Crypto partition back in). 
    PSA_CRYPTO has a devicetree-gated "default y" (nrf_security/Kconfig) that fires whenever a zephyr,psa-crypto-rng node is present, regardless of any app Kconfig. Left unset, it silently re-enables PSA_CRYPTO_PROVIDER_TFM, which `select`s TFM_PARTITION_CRYPTO back on. Must be explicitly disabled. Measured cost of allowing this: TF-M needs ~37,180 B RAM / 56,056 B flash with Crypto on, vs. 6,132 B RAM / 23,128 B flash with Crypto off."

    Coming up with a minimal project may take time and I don't want to slow up your team's deliberations trying to find a clean workaround. I think you'll find that others will have the same problem too. I would be glad to know if forcing PSA_CRYPTO on is part of some grand plan that I should be aware of. As you can see from my app footprint, resources are already tight.

    It seems to me that my hack can already show that making PSA_CRYPTO's inclusion optional doesn't seem to hurt.

  • Hi Regan, 
    Thanks for the feedback. But I'm not so sure why the modem_shell doesn't have the same problem ? 


    From what I can see in the \build\modem_shell\zephyr\.config we do have: 

    CONFIG_MBEDTLS=y

    CONFIG_PSA_CRYPTO_PROVIDER_TFM=y

    CONFIG_PSA_CRYPTO=y

    But the TFM partition of the sample takes only 6152 B as shown in the previous reply. 

    Have you configured CONFIG_TFM_PROFILE_TYPE_MINIMAL=y ? 

    What make the modem_shell difference from yours ? 

Reply
  • Hi Regan, 
    Thanks for the feedback. But I'm not so sure why the modem_shell doesn't have the same problem ? 


    From what I can see in the \build\modem_shell\zephyr\.config we do have: 

    CONFIG_MBEDTLS=y

    CONFIG_PSA_CRYPTO_PROVIDER_TFM=y

    CONFIG_PSA_CRYPTO=y

    But the TFM partition of the sample takes only 6152 B as shown in the previous reply. 

    Have you configured CONFIG_TFM_PROFILE_TYPE_MINIMAL=y ? 

    What make the modem_shell difference from yours ? 

Children
  • The Build fails with CONFIG_TFM_PROFILE_TYPE_MINIMAL=y 

    It also fails if I try CONFIG_TFM_CMAKE_BUILD_TYPE_MINSIZEREL=y, unless I useCMake to strip out PSA_CRYPTO.

    Here are the warnings I get:

    warning: TFM_PARTITION_CRYPTO (defined at C:/ncs/v3.4.0/nrf/modules/..\modules/trusted-
    firmware-m/Kconfig.tfm_minimal.defconfig:20, C:/ncs/v3.4.0/nrf/modules/trusted-
    firmware-m\Kconfig.tfm.defconfig:86, C:/ncs/v3.4.0/zephyr/modules/trusted-
    firmware-m/Kconfig.tfm.partitions:31, modules\trusted-firmware-m\Kconfig.tfm.partitions:31) was
    assigned the value 'n' but got the value 'y'. See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_TFM_PARTITION_CRYPTO and/or look up
    TFM_PARTITION_CRYPTO in the menuconfig/guiconfig interface. The Application Development Primer,
    Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be
    helpful too.
    
    
    warning: UPDATEABLE_IMAGE_NUMBER (defined at
    C:/ncs/v3.4.0/nrf/modules/..\samples\common\mcumgr_bt_ota_dfu/Kconfig:87, subsys/dfu/Kconfig:97) was
    assigned the value '1' but got the value ''. Check these unsatisfied dependencies:
    (((BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS) && SOC_SERIES_NRF53 &&
    NCS_SAMPLE_MCUMGR_BT_OTA_DFU) || (!MCUBOOT && IMG_MANAGER)) (=n). See
    http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_UPDATEABLE_IMAGE_NUMBER and/or look up
    UPDATEABLE_IMAGE_NUMBER in the menuconfig/guiconfig interface. The Application Development Primer,
    Setting Configuration Values, and Kconfig - Tips and Best Practices sections of the manual might be
    helpful too.
    
    
    warning: MCUBOOT_UPDATE_FOOTER_SIZE (defined at subsys/dfu/Kconfig:55) was assigned the value '0x30'
    but got the value ''. Check these unsatisfied dependencies: MCUBOOT_IMG_MANAGER (=n), IMG_MANAGER
    (=n). See http://docs.zephyrproject.org/latest/kconfig.html#CONFIG_MCUBOOT_UPDATE_FOOTER_SIZE and/or
    look up MCUBOOT_UPDATE_FOOTER_SIZE in the menuconfig/guiconfig interface. The Application
    Development Primer, Setting Configuration Values, and Kconfig - Tips and Best Practices sections of
    the manual might be helpful too.
    
    error: Aborting due to Kconfig warnings
    
    CMake Error at C:/ncs/v3.4.0/zephyr/cmake/modules/kconfig.cmake:424 (message):
      command failed with return code: 1
    Call Stack (most recent call first):
      C:/ncs/v3.4.0/zephyr/cmake/modules/zephyr_default.cmake:129 (include)
      C:/ncs/v3.4.0/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
      C:/ncs/v3.4.0/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:97 (include_boilerplate)
      CMakeLists.txt:15 (find_package)

    I get this additional warning if _MINSIZEREL is y

    warning: PSA_WANT_ALG_HMAC_DRBG (defined at C:/ncs/v3.4.0/nrf/modules/..\subsys\nrf_security\src/drivers/Kconfig:49) has direct dependencies PSA_WANT_GENERATE_RANDOM && PSA_CRYPTO && NRF_SECURITY with value n, but is currently being y-selected by the following symbols:
     - TFM_PROFILE_TYPE_MINIMAL (defined at C:/ncs/v3.4.0/nrf/modules/trusted-firmware-m/Kconfig:329), with value y, direct dependencies <choice TFM_PROFILE_TYPE> (value: y), and select condition <choice TFM_PROFILE_TYPE> (value: y)
    Parsing C:/Github/myproject/Kconfig
    Loaded configuration 'C:/ncs/v3.4.0/zephyr/boards/nordic/nrf9151dk/nrf9151dk_nrf9151_ns_defconfig'
    Merged configuration 'C:/Github/myproject/prj.conf'
    Merged configuration 'C:/Github/myproject/debug.conf'
    Merged configuration 'C:/Github/myproject/extra.conf'
    Merged configuration 'C:/Github/myproject/build/myproject/zephyr/misc/generated/extra_kconfig_options.conf'
    Merged configuration 'C:/Github/myproject/build/myproject/zephyr/.config.sysbuild'

    Here is my conf file (I have a separate one just for TFM):

    #
    # TF-M and app overlay (NCS 3.4.0 / Zephyr 4.4)
    #
    # This build consumes CONFIG_TFM_* symbols from the app configuration path.
    # Keep TF-M partition/module settings here rather than in sysbuild/tfm.conf.
    
    CONFIG_BUILD_WITH_TFM=y
    
    # nRF Cloud uses modem-managed TLS credentials and socket offload, so the app
    # itself never calls into MBEDTLS/PSA Crypto. MBEDTLS cannot be disabled here:
    # BUILD_WITH_TFM has `imply MBEDTLS if !TFM_USE_NS_APP` (Kconfig.tfm), and
    # because MBEDTLS's prompt is conditional ("bool ... if !MBEDTLS_PROMPTLESS"),
    # an explicit `# CONFIG_MBEDTLS is not set` is silently ignored by Kconfig -
    # MBEDTLS gets forced to 'y' regardless (see the "assigned 'n' but got 'y'"
    # warning). The forced-on mbed TLS 4.x library then fails to compile with
    # PSA_CRYPTO off (mbedtls_error_pair_t only exists under
    # MBEDTLS_PSA_CRYPTO_CLIENT, which is "def_bool y depends on PSA_CRYPTO").
    # Kconfig-level workarounds are dead ends in NCS 3.4.0 (MBEDTLS_CUSTOM is
    # blocked by an nrf_security CMake FATAL_ERROR; select of
    # MBEDTLS_PSA_CRYPTO_CLIENT is a hard Zephyr Kconfig error). Instead,
    # MYPROJECT_STRIP_MBEDTLS (project Kconfig + CMakeLists.txt) stubs out the
    # unused mbed TLS library target at the CMake level so PSA_CRYPTO and
    # TFM_PARTITION_CRYPTO can stay off (saves ~24 KiB secure SRAM + ~33 KB
    # TF-M flash vs. letting the Crypto partition back in).
    # CONFIG_ENTROPY_PSA_CRYPTO_RNG is not set
    
    # PSA_CRYPTO has a devicetree-gated "default y" (nrf_security/Kconfig) that
    # fires whenever a zephyr,psa-crypto-rng node is present, regardless of any
    # app Kconfig. Left unset, it silently re-enables PSA_CRYPTO_PROVIDER_TFM,
    # which `select`s TFM_PARTITION_CRYPTO back on. Must be explicitly disabled.
    # Measured cost of allowing this: TF-M needs ~37,180 B RAM / 56,056 B flash
    # with Crypto on, vs. 6,132 B RAM / 23,128 B flash with Crypto off.
    # CONFIG_PSA_CRYPTO is not set
    
    # Silence TF-M logs forwarded to NS world
    CONFIG_TFM_LOG_LEVEL_SILENCE=y
    
    # Minimal profile pulls in services we no longer want.
    CONFIG_TFM_PROFILE_TYPE_NOT_SET=y
    # CONFIG_TFM_PROFILE_TYPE_MINIMAL is not set
    
    # Force TF-M to be size-optimized even when app uses debug build.
    # This is an app-side Kconfig that controls the TF-M ExternalProject build type.
    CONFIG_TFM_CMAKE_BUILD_TYPE_MINSIZEREL=y
    
    # Keep only the platform service needed by current NS reboot paths.
    CONFIG_TFM_PARTITION_PLATFORM=y
    # CONFIG_TFM_PARTITION_CRYPTO is not set
    # CONFIG_TFM_PARTITION_INTERNAL_TRUSTED_STORAGE is not set
    # CONFIG_TFM_PARTITION_PROTECTED_STORAGE is not set
    # CONFIG_TFM_PARTITION_INITIAL_ATTESTATION is not set
    CONFIG_TFM_ALLOW_NON_SECURE_RESET=y
    # CONFIG_TFM_ALLOW_NON_SECURE_FAULT_HANDLING is not set
    
    # CONFIG_TFM_SECURE_UART is not set
    

    By default, I'm using CMake to strip out PSA_CRYPTO. If I don't do that, build fails.

    I also note that I am using a DEBUG build.

Related