MQTT over Thread

Today I am attempting to set up an MQTT connection from a Thread device to an MQTT server on the Internet (for better or for worse, if this is a terrible idea I'm open to suggestions).

I've done some preliminary investigation using the Thread CLI example and am now starting to develop code using the Thread API in SDK 2.6.0.  I have a border router running on an RPi with NAT64.

At this point I can do a DNS lookup using otDnsClientResolveIp4Address, sending the request to fd34:e64f:ccd9:02:0:0:808:808 (i.e. 8.8.8.8) and I get back the address of the MQTT server as a synthesized IPv6 address.  I can ping this address and get a response.

The next step is to attempt an MQTT connection. 

I start by calling getaddrinfo() to resolve the IP address of the broker, this fails with -ENOENT, it's the same whether I use hints.ai_family = AF_INET or AF_INET6.

So instead I tried using the address returned by the earlier DNS lookup.  Then I call mqtt_connect() but get -EPROTOTYPE (protocol wrong type for socket).

I see some discussion in DevZone from people trying to do similar things but none quite the same as this.  Perhaps I'm being naive thinking that it should 'just work'?

Any suggestions will be gladly received.

Thanks,

  Frog

Parents
  • Hi Frog,

    If you search MQTT_TRANSPORT_SECURE in NCS source codes, you will find some samples about to properly set up TLS connection in MQTT.

    Hope this will give you some hint.

    Best regards,

    Charlie

  • Currently I'm able to request a subset of the default ciphersuites, which is a step in the right direction.  The suite that I want to use isn't in that list though.  Looking in ssl_cipersuites.c I see that I need (at least) CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED

    although this depends on CONFIG_MBEDTLS_RSA_C and CONFIG_MBEDTLS_PKCS1_V15, and ultimately on CONFIG_MBEDTLS_LEGACY_CRYPTO_C.  The last of these breaks OpenThread.

    I see that this is a reversal of the situation described here
    PSA crypto features not enabled when CONFIG_MBEDTLS_LEGACY_CRYPTO_C is enabled
    where CONFIG_MBEDTLS_LEGACY_CRYPTO_C used to be required by OT.

    It's my intention to use PSA throughout, so I have CONFIG_OPENTHREAD_CRYPTO_PSA and CONFIG_MBEDTLS_PSA_CRYPTO_C and a few CONFIG_PSA_WANT... so I'm not clear on why I would need LEGACY_CRYPTO_C - are you able to shed any light on this?

  • Thanks for your patience, I've been dealing with some other matters for a few days.

    Looking at the CLI example some more, the default configuration opens a TCP connection and then attempts TLS negotiation with the default ciphersuites (using SDK2.5.1).  However, when I set CONFIG_MBEDTLS_LEGACY_CRYPTO_C=y it seems to break - the initial TCP connection packet should just have the SYN flag set but with LEGACY_C it has SYN, ECN and CWR according to Wireshark, and there's no response from the server.

    I know from this post  PSA crypto features not enabled when CONFIG_MBEDTLS_LEGACY_CRYPTO_C is enabled that specifying LEGACY_C causes some PSA functionality to be lost.  Given that the legacy APIs are deprecated it makes sense that I would aim not to use them but should use the PSA APIs, and logically I'd use SDK 2.6.0 where OpenThread uses PSA too.

    So I'm back to the problem of wanting to specify one additional RSA-based cipersuite in addition to those that OT needs.  As far as I can see (please tell me if I'm wrong) I should be able to use the precompiled openThread library provided that I also provide a PSA suite that at least satisfies OT.

    Since I need an RSA-based cipersuite, is it essential to enable the legacy APIs (which the dependency tree seems to suggest) or is there another way to do this?

  • Hi Frog,

    Welcome back!

    Frog said:
    I'm back to the problem of wanting to specify one additional RSA-based cipersuite in addition to those that OT needs.  As far as I can see (please tell me if I'm wrong) I should be able to use the precompiled openThread library provided that I also provide a PSA suite that at least satisfies OT.

    You are free to do this on your application codes. The certification should be OK according to Certification by inheritance without modifications to binaries, but if you use deprecated Mbed TLS support by setting the CONFIG_OPENTHREAD_NRF_SECURITY_CHOICE Kconfig option to y, but you must build the Thread libraries from source, the Certification by inheritance with modifications to binaries need to be followed.

    Frog said:
    Since I need an RSA-based cipersuite, is it essential to enable the legacy APIs (which the dependency tree seems to suggest) or is there another way to do this?

    As far as I know, using legacy APIs is the shortest way to achieve your target.

    However, it's important to note that combining legacy and PSA crypto APIs in the same application might work, but it's not a recommended or maintained solution. 

    Best regards,

    Charlie

  • Hi Charlie,

      Since last time I have moved from a Thingy91 to a Fanstel BT40NE module which is based on an nRF5340 and has a 21540 FEM, which I've got working with some SDK adjustments as recommended by Fanstel.  I'm more or less back where I was with the MQTT connection - the device sends a hello request to the server but with the default list of ciphersuites.

    I've copied the config from here
    RE: Error -22 in mqtt_connect() - nRF52840dk with Azure IoT Hub using OpenThread and TCP
    and resolved a few issues, now I'm down to three problems that appear to be closely related: MBEDTLS_CIPHER_AES_ENABLED, MBEDTLS_CIPHER_CCM_ENABLED and MBEDTLS_MAC_CMAC_ENABLED.  The error messages such as

    warning: MBEDTLS_CIPHER_AES_ENABLED (defined at C:/nordic/v2.6.1/zephyr/modules/mbedtls\Kconfig.tls-generic:257, modules\mbedtls\Kconfig.tls-generic:257) has direct dependencies (!(NRF_SECURITY || NORDIC_SECURITY_BACKEND) && MBEDTLS_BUILTIN && MBEDTLS_CFG_FILE = "config-tls-generic.h" && MBEDTLS) || (!(NRF_SECURITY || NORDIC_SECURITY_BACKEND) && MBEDTLS_BUILTIN && MBEDTLS_CFG_FILE = "config-tls-generic.h" && MBEDTLS && 0) with value n, but is currently being y-selected by the following symbols:
     - OPENTHREAD_MBEDTLS (defined at subsys/net/l2/openthread/Kconfig:179), with value y, direct dependencies NET_L2_OPENTHREAD && NETWORKING (value: y), and select condition NET_L2_OPENTHREAD && NETWORKING (value: y)

    tell me that OpenThread requires these set to 'y' but they are forced to 'n' because CONFIG_MBEDTLS_BUILTIN=n, in turn because I don't have MBEDTLS_IMPLEMENTATION set and I'm not sure how to do that.

    I'm currently using SDK v2.6.1 and getting ready to move to v2.7.0.

    Are you able to give any guidance please?

  • Hi Frog,

    Could you have a quick try to enable configure NRF_SECURITY_LEGACY_AND_PSA?

    config NRF_SECURITY_LEGACY_AND_PSA
        bool
        default y
        select EXPERIMENTAL
        depends on MBEDTLS_LEGACY_CRYPTO_C && MBEDTLS_PSA_CRYPTO_C
        # This configuration doesn't affect TF-M builds since the PSA
        # APIs are provided by TF-M.
        # When this configuration is enabled we manually enable
        # some symbols in the build_config.h file in the Oberon PSA core.
        # This requires only the Oberon PSA crypto driver to be enabled,
        # it requires the CC3XX platform library to get random data and
        # the trusted storage for ITS support. The depenedencies here
        # match what we enable in the build_config.h file so if we need to
        # modify the dependencies here we also need to modify the build_config.h.
        depends on PSA_CRYPTO_DRIVER_OBERON && !PSA_CRYPTO_DRIVER_CC3XX
        depends on NRF_CC3XX_PLATFORM
        depends on TRUSTED_STORAGE
        depends on !BUILD_WITH_TFM
        help
           This is an option to support legacy mbedTLS and PSA crypto APIs
           at the same time. This is not recommended as it is not fully
           supported in our system. This feature might get changed/removed at
           any time in the future. You are advised to use the PSA APIs
           for any new developments.

           This option doesn't use the nrf_security for the internal
           PSA configuration. It always use the Oberon PSA driver
           for all the crypto operations expect for the PRNG which
           uses the nrf_cc3xx_platform library.
    Best regards,
    Charlie
  • It's not possible to set NRF_SECURITY_LEGACY_AND_PSA directly, so I set

    CONFIG_NRF_CC3XX_PLATFORM=y
    CONFIG_TRUSTED_STORAGE=y
    CONFIG_BUILD_WITH_TFM=n

    which conflicted with many of the crypto library options I'd already requested, e.g.

    #CONFIG_MBEDTLS_AES_C=y

    so I commented out all the offending definitions.  This left me with:

    warning: HW_UNIQUE_KEY (defined at C:/nordic/v2.6.1/nrf\lib\hw_unique_key/Kconfig:35) has direct dependencies HW_UNIQUE_KEY_SUPPORTED && (NRF_CC3XX_PLATFORM || BUILD_WITH_TFM) && NRF_SECURITY && (MPU_ALLOW_FLASH_WRITE || BUILD_WITH_TFM) && (!BUILD_WITH_TFM || TFM_CRYPTO_BUILTIN_KEYS) with value n, but is currently being y-selected by the following symbols:
     - TRUSTED_STORAGE_BACKEND_AEAD_KEY_DERIVE_FROM_HUK (defined at C:/nordic/v2.6.1/nrf\subsys\trusted_storage/Kconfig:132), with value y, direct dependencies HW_UNIQUE_KEY_SUPPORTED && <choice TRUSTED_STORAGE_BACKEND_AEAD_KEY> (value: y), and select condition HW_UNIQUE_KEY_SUPPORTED && <choice TRUSTED_STORAGE_BACKEND_AEAD_KEY> (value: y)

    warning: SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 (defined at soc/arm/nordic_nrf\nrf53\Kconfig.soc:147) has direct dependencies NRF_SOC_SECURE_SUPPORTED && SOC_NRF5340_CPUAPP && SOC_SERIES_NRF53X && SOC_FAMILY_NRF with value n, but is currently being y-selected by the following symbols:
     - BOARD_ENABLE_CPUNET (defined at C:/nordic/v2.6.1/zephyr/boards/arm/nrf5340dk_nrf5340/Kconfig:23), with value y, direct dependencies BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS (value: y), and select condition BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS (value: y)

    Given that this is all internal to the SDK I don't know if there's anything I can do to work around it.

    I'm worried about getting too far into the weeds without having a really good understanding of what OpenThread needs.  If I understand correctly there's one crypto library that's used system-wide, and this needs to provide the superset of what OT needs and what my TLS connection needs.  Is that correct?  If so it would make sense to start with the default OT configuration and then add the ciphersuite that I need, although I suppose that may mean I have to build the library from source rather than linking a precompiled library.

  • Reply
    • It's not possible to set NRF_SECURITY_LEGACY_AND_PSA directly, so I set

      CONFIG_NRF_CC3XX_PLATFORM=y
      CONFIG_TRUSTED_STORAGE=y
      CONFIG_BUILD_WITH_TFM=n

      which conflicted with many of the crypto library options I'd already requested, e.g.

      #CONFIG_MBEDTLS_AES_C=y

      so I commented out all the offending definitions.  This left me with:

      warning: HW_UNIQUE_KEY (defined at C:/nordic/v2.6.1/nrf\lib\hw_unique_key/Kconfig:35) has direct dependencies HW_UNIQUE_KEY_SUPPORTED && (NRF_CC3XX_PLATFORM || BUILD_WITH_TFM) && NRF_SECURITY && (MPU_ALLOW_FLASH_WRITE || BUILD_WITH_TFM) && (!BUILD_WITH_TFM || TFM_CRYPTO_BUILTIN_KEYS) with value n, but is currently being y-selected by the following symbols:
       - TRUSTED_STORAGE_BACKEND_AEAD_KEY_DERIVE_FROM_HUK (defined at C:/nordic/v2.6.1/nrf\subsys\trusted_storage/Kconfig:132), with value y, direct dependencies HW_UNIQUE_KEY_SUPPORTED && <choice TRUSTED_STORAGE_BACKEND_AEAD_KEY> (value: y), and select condition HW_UNIQUE_KEY_SUPPORTED && <choice TRUSTED_STORAGE_BACKEND_AEAD_KEY> (value: y)

      warning: SOC_NRF_GPIO_FORWARDER_FOR_NRF5340 (defined at soc/arm/nordic_nrf\nrf53\Kconfig.soc:147) has direct dependencies NRF_SOC_SECURE_SUPPORTED && SOC_NRF5340_CPUAPP && SOC_SERIES_NRF53X && SOC_FAMILY_NRF with value n, but is currently being y-selected by the following symbols:
       - BOARD_ENABLE_CPUNET (defined at C:/nordic/v2.6.1/zephyr/boards/arm/nrf5340dk_nrf5340/Kconfig:23), with value y, direct dependencies BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS (value: y), and select condition BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF5340DK_NRF5340_CPUAPP_NS (value: y)

      Given that this is all internal to the SDK I don't know if there's anything I can do to work around it.

      I'm worried about getting too far into the weeds without having a really good understanding of what OpenThread needs.  If I understand correctly there's one crypto library that's used system-wide, and this needs to provide the superset of what OT needs and what my TLS connection needs.  Is that correct?  If so it would make sense to start with the default OT configuration and then add the ciphersuite that I need, although I suppose that may mean I have to build the library from source rather than linking a precompiled library.

    Children
    No Data
    Related