How to integrate MBEDTLS for nrf9160 and native simulation on sdk 2.6?

Dear Support Team

My goal is to build an application for two targets. The targets are an nrf9160 and a simulation target for running it natively on Linux (currently trying native_sim).

The application makes use of the mbedtls-API. For example the `mbedtls_x509...`, `mbedtls_ecp` etc...

To build it for the nrf9160 it works fine now with the following config:

```
CONFIG_MBEDTLS_TLS_LIBRARY=y
CONFIG_MBEDTLS_PK_WRITE_C=y
CONFIG_MBEDTLS_ECP_C=y
CONFIG_MBEDTLS_DHM_C=y
CONFIG_MBEDTLS_X509_CREATE_C=y
CONFIG_MBEDTLS_X509_CSR_WRITE_C=y
CONFIG_MBEDTLS_X509_CRT_PARSE_C=y
CONFIG_MBEDTLS_X509_LIBRARY=y
CONFIG_MBEDTLS_X509_USE_C=y
CONFIG_MBEDTLS_ENABLE_HEAP=y
CONFIG_MBEDTLS_HEAP_SIZE=59000
CONFIG_MBEDTLS_SSL_SERVER_NAME_INDICATION=y
CONFIG_MBEDTLS_PKCS1_V15=y
CONFIG_MBEDTLS_RSA_C=y
CONFIG_MBEDTLS_CMAC_C=n
CONFIG_MBEDTLS_PSA_CRYPTO_C=y
CONFIG_MBEDTLS_GCM_C=y
CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=16384
CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
CONFIG_MBEDTLS_SHA384_C=n
CONFIG_MBEDTLS_SHA512_C=n
CONFIG_MBEDTLS_CIPHER_MODE_XTS=n
CONFIG_MBEDTLS_CIPHER_MODE_CBC=n
CONFIG_MBEDTLS_CIPHER_MODE_CTR=y
CONFIG_MBEDTLS_CHACHA20_C=n
CONFIG_MBEDTLS_ECDSA_DETERMINISTIC=n
CONFIG_MBEDTLS_SSL_SRV_C=n
CONFIG_MBEDTLS_ECDH_C=n
CONFIG_MBEDTLS_PKCS1_V21=n
CONFIG_MBEDTLS_CCM_C=n
CONFIG_MBEDTLS_POLY1305_C=n
CONFIG_MBEDTLS_HKDF_C=n

```

Furthermore, we had to modify the `modules/mbedtls/configs/config-tls-generic.h`-file slightly with some hardcoded `defines`.

But I am struggling to build it for native_sim. The problem is, that I can not enable the respective Kconfigs. For example:

```

warning: MBEDTLS_X509_LIBRARY (defined at /opt/zephyrproject/nrf/modules/trusted-
firmware-m/Kconfig.mbedtls_minimal.defconfig:32,
/opt/zephyrproject/nrf/subsys/nrf_security/Kconfig.tls:7) was assigned the value 'y' but got the
value 'n'. Check these unsatisfied dependencies: (TFM_PROFILE_TYPE_MINIMAL || NRF_SECURITY) (=n).

```

Furthermore, I have observed the following:

The library can be included via the `nrf-sdk`-west.yml or via `sdk-zephyr`-west.yml. Both of those will pull in a different state it seems:

Both refer to the mbedtls fork here: https://github.com/nrfconnect/sdk-mbedtls

But then there is also upstream mbedtls, that is pulled in by upstream zephyr, that seems to offer different options then the `sdk-mbedtls`-fork, like `CONFIG_MBEDTLS_BUILTIN`: https://github.com/zephyrproject-rtos/mbedtls

This confuses me a bit. And I can summarize my questions this way:

  • Which mbedtls-version to use with `sdk-2.6` (sdk vs upsteam, revision v3.5.2-ncs1 vs revision 66ed2279d6222056af172c188eaf4dcfed481032) ?
  • Which way do you recommend to configure MBEDTLS to achieve the goal described above? Could we use `CONFIG_MBEDTLS_CFG_FILE` instead?
  • How can we do all this, while ensuring, that hardware-crypto-acceleration is used when building for the nrf9160?

Thanks in advance and let me know, if you need additional information.

  • Hi Cla,

    Which mbedtls-version to use with `sdk-2.6` (sdk vs upsteam, revision v3.5.2-ncs1 vs revision 66ed2279d6222056af172c188eaf4dcfed481032) ?

    sdk-nrf is the boss of west includes. See west.yml.
    name-allowlist decides which repos zephyr are allowed to include. Since mbedtls is not here, we know that mbedtls is not from zephyr.

    The two previous links was for main, but for v2.6.0 we now change to that. Here we can scroll down and find that mbedtls uses v3.5.2-ncs1.

    To verify this we can navigate in git bash to "ncs/modules/crypto/mbedtl" and do "git log":

    commit acea48fc8a5eb227033b55e6ec012731218e257f (HEAD, tag: v3.3.0-ncs2-rc2, tag: v3.3.0-ncs2-2, tag: v3.3.0-ncs2-1-rc1, tag: v3.3.0-ncs2-1, tag: v3.3.0-ncs2, manifest-rev)
    Author: Frank Audun Kvamtrø <[email protected]>
    Date:   Tue Oct 17 09:13:17 2023 +0200
    
        [nrf noup]  Fix buffer overread with stream cipher
        
        Recreated from commit faf0b8604ac49456b0cff7a34ad27485ca145cce
        which provides the following information
        
        "With stream ciphers, add a check that there's enough room to read a MAC
        in the record. Without this check, subtracting the MAC length from the
        data length resulted in an integer underflow, causing the MAC calculation
        to try reading (SIZE_MAX + 1 - maclen) bytes of input, which is a buffer
        overread."
        
        This commit is a "noup" since TLS/DTLS is undergoing refactoring and
        the content of the commit had to be recreated.
        
        Signed-off-by: Frank Audun Kvamtrø <[email protected]>
    

    How can we do all this, while ensuring, that hardware-crypto-acceleration is used when building for the nrf9160?

    The hope is that zephyrs board-definition feature will be able to make sure that this works as expected.
    You should still verify this after it looks like it works though.

    Which way do you recommend to configure MBEDTLS to achieve the goal described above? Could we use `CONFIG_MBEDTLS_CFG_FILE` instead?

    I think you need to do this step by step. Why does it fail now?
    Then create boards/native_sim.conf and add configurations needed for this board there until it works.
    And/or move configs from prj.conf to boards/nrf9160dk_nrf9160_ns.conf which are not needed for native_sim also.

    Check these unsatisfied dependencies: (TFM_PROFILE_TYPE_MINIMAL || NRF_SECURITY) (=n).

    Use VS Code extension Kconfig search of "west build -t menuconfig" to find which of these are "n" and then figure out why those are "n" and if you can make them become "y".

    Regards,
    Sigurd Hellesvik

  • Use VS Code extension Kconfig search of "west build -t menuconfig" to find which of these are "n" and then figure out why those are "n" and if you can make them become "y".

    Thanks for the quick reply.

    I consider the first part of my question answered and understand, that for `sdk 2.6` we should use the MBEDTLS linked in the `west.yml` from `sdk-nrf`.

    This leaves the second part all the more unclear. How can certain features of MBEDTLS be configured for native_sim?

    Lets take another look at the above mentioned config. As you point out there are the two unsatisfied dependencies (TFM_PROFILE_TYPE_MINIMAL || NRF_SECURITY) . Now neither of those can be activated to work with native_sim. For starter native_sim is not a NORDIC_SOC so NRF_SECURITY is not possible. On the other hand it does also not support TFM such that TFM_PROFILE_TYPE_MINIMAL can not be activated.

    I hope, that I could clarify my question about how to configure MBEDTLS in the above mentioned circumstances?

  • Alternatively, are there other options for running a simulation target except native_sim?

  • Cla said:
    Alternatively, are there other options for running a simulation target except native_sim?

    Not sure if it is better or not, but Renode exists:

    https://renodepedia.renode.io/boards/nrf9160dk_nrf9160/?view=software&demo=hello_world

    However, I think/hope it should be possible to make native_sim work here also.
    Are you able to find a sample and/or minimal sample I can reproduce your issue on?
    I find it odd that these are the dependencies, as I can not find them in the definition of MBEDTLS_X509_LIBRARY. (nrf/subsys/nrf_security/Kconfig.tls)

    Check these unsatisfied dependencies: (TFM_PROFILE_TYPE_MINIMAL || NRF_SECURITY) (=n).
  • `nrf/subsys/nrf_security/Kconfig.tls` is sourced conditionally. It is only available if NRF_SECURITY is active. See line 47 of `nrfxlib/nrf_security/Kconfig`:

    ```
    if NRF_SECURITY

    ...

    # Include TLS/DTLS and x509 configurations
    rsource "Kconfig.tls"

    ...

    endif # NRF_SECURITY

    ```

Related