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.

Parents
  • 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

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

  • I am honestly a bit new to the whole testing stuff.

    So to learn, I have talked with a colleguea who knows more than me, and I think the first question to ask is:

    What exactly do you want to test?
    Is this a unit test or an integration test?

  • We have some unit-test in place. They use the native-posix board with `CONFIG_ASAN` and `CONFIG_UBSAN` activated. We run the unit-test directly on the hardware also.

    In addition we would like to do some integration/system-testing with a simulation setup.In the past we have used `qemu`, but it is not possible to activate `CONFIG_ASAN` to my knowledge. We are evaluating `native_sim` (released with zephyr 3.5) to do system-testing in a simulation environment that allows us to use native debugging tools and other tooling like above mentioned address sanitizer.

    Edit: on the hardware we run the unit tests without CONFIG_ASAN and CONFIG_UBSAN, because they are not supported to our knowledge.

  • The status on this ticket is that I have asked our crypto developers if they have any ideas here.

  • Speaking of the Dev, they just answered:

    "

    This is not something we claim to support. The NCS MbedTLS config is coupled with building for our products.

    I have no idea if their use case is feasible, I suspect it would require a lot of config and build system voodoo, but I don't think we can support them on this. You are probably as likely as any of the developers to be able to provide advice here.

    "
    So yea, I can spend some time to try and build a crypto sample for native_sim, but i would not have high hopes. As they say the tight coupling between our SoC and libraries may make this hard.

    One alternative would be to disable crypto for your project, but that might make the whole exercise a bit pointless?

  • Thanks for the quick reply. Disabling and Mocking the crypto-stuff could be an option.

    I was just wondering, if there is a supported way to achieve this, since software implementations for Mbedtls exists.

Reply Children
  • Doing some testing:

    zephyr/samples/drivers/crypto works with native_sim

    zephyr/samples/tfm_integration/tfm_psa_test does not work  with native_sim (even with vanilla zephyr)

    So to sum up parts that might have problems with native_sim:

    • Modem networking
      • Fix: Assuming IP works for native_sim, configure networking to use that instead
    • TF-M
      • I assume you need this?
      • Not sure how or if to fix this for native_sim at the moment.
    • Crypto
      • Which APIs do you currently use in your code?
      • Fix: I have never tried Mbedtls-shim before, but look into using that
    • HW specific components
      • Fix: Simulate

    Do you agree with this summary?
    Am I missing something? Do you disagree with anything?

  • Thank you for analyzing this.

    Which APIs do you currently use in your code?

    mbedtls_aes
    mbedtls_ecp
    mbedtls_mpi
    mbedtls_pk
    mbedtls_rsa
    mbedtls_sha256
    mbedtls_x509write

    My understanding is, that when building for nrf9160 with tfm activated, it will use the "alternative" implementation, when building with tfm. This will then cause the calls to be redirected to tfm-crypto?

    CONFIG_MBEDTLS_ENTROPY_HARDWARE_ALT=y
    CONFIG_MBEDTLS_AES_SETKEY_ENC_ALT=y
    CONFIG_MBEDTLS_AES_SETKEY_DEC_ALT=y
    CONFIG_MBEDTLS_AES_ENCRYPT_ALT=y

    ...

    As for native_sim, the goal would be to use above libraries in their software implementation.

    TF-M
    • I assume you need this?

    My understanding is, that this is not currently possible with native_sim. I heard it works on qemu with https://docs.zephyrproject.org/latest/boards/arm/mps2/doc/mps2_an521.html but never tested. So if it uses the software implementation of the mbedtls libraries, I think it is not needed for native sim.

    Do you agree with this summary?
    Am I missing something? Do you disagree with anything?

    Yes, sounds good. Maybe I did not clarify my expectation clearly. For example the library `mbedtls_x509write` can be used on the nrf9160 without problem, but it can not be used with native sim, because it is not possible to activate the respective Kconfig option. But my expectation is, that it is possible, because I expect a software implementation of the `mbedtls_x509write`-interface to be available.

    Let me know, if I could explain my expectation and/or goal in a better way?

    Thanks on the support so far.

  • Cla said:
    Maybe I did not clarify my expectation clearly. For example the library `mbedtls_x509write` can be used on the nrf9160 without problem, but it can not be used with native sim, because it is not possible to activate the respective Kconfig option. But my expectation is, that it is possible, because I expect a software implementation of the `mbedtls_x509write`-interface to be available.

    Let me know, if I could explain my expectation and/or goal in a better way?

    I found one developer in nordic with native_sim experience, and asked ca:
    "And SW mbedtls should not be too hard to make work with native_sim?"
    He answers:
    "it works already (at least in plain zephyr:
    tests/crypto/mbedtls/ builds and runs fine for native_sim )
    and it is used in quite a few other tests and samples
    "

    Can you take a look at that test and see if what you need is there?

Related