ARMmbed

Using mbedTLS MQTT in Tiva C series without RTOS

Hi, I am trying to implement tls/mqtt using mbedtls library. I got reference from below link: “https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/FRDM-K64F/FRDM-K64F_lwip_lwip_mqtt_bm/source
In this, after performing “mqtt_do_connect()” step, it gives me error in “mqtt_do_tls_handshake()” step.

In mbedtls_ssl_handshake() function, ‘if( ssl == NULL || ssl->conf == NULL )’ this condition is set to true because ssl->conf is null and it returns me an error MBEDTLS_ERR_SSL_BAD_INPUT_DATA.

Here is my TLS init code:

mbedtls_entropy_init( &stentropy );
mbedtls_ctr_drbg_init( &stctr_drbg );
mbedtls_x509_crt_init( &stcacert );
mbedtls_ssl_config_init( &stconf );
mbedtls_ssl_init( &stssl );
if( ( ret = mbedtls_ssl_config_defaults( &stconf,
MBEDTLS_SSL_IS_CLIENT,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT ) ) != 0 )
{
LWIP_DEBUGF(MQTT_APP_DEBUG_TRACE,( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret ));
printf( " failed\n ! mbedtls_ssl_config_defaults returned %d\n\n", ret );
return -1;
}
mbedtls_ssl_conf_authmode(&stconf, MBEDTLS_SSL_VERIFY_NONE);
mbedtls_ssl_conf_rng( &stconf, mbedtls_ctr_drbg_random, &stctr_drbg );
mbedtls_ssl_conf_dbg( &stconf, my_debug, stdout );
mbedtls_ssl_setup(&stssl, &stconf);

if(CONFIG_BROKER_HOST_NAME!=NULL && ( ret = mbedtls_ssl_set_hostname(&stssl, CONFIG_BROKER_HOST_NAME) ) != 0 )
{
LWIP_DEBUGF(MQTT_APP_DEBUG_TRACE,( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret ));
printf( " failed\n ! mbedtls_ssl_set_hostname returned %d\n\n", ret );
return -1;
}
/* the SSL context needs to know the input and output functions it needs to use for sending out network traffic. */
// mbedtls_ssl_set_bio(&ssl, &mqtt_client, mbedtls_net_send, mbedtls_net_recv, NULL);
mbedtls_ssl_set_bio(&stssl, stAPP_MQTT_Msg_t->pstmqtt_client, MT_Mbedtls_Send, MT_Mbedtls_Recv, NULL);

Thanks in advance.

Hi @urvishah
Your TLS init seems to be correct.

The call to mbedtls_ssl_setup(&stssl, &stconf); should have assigned&stconf to ssl->conf, so it shouldn’t have been NULL.
Have you checked that mbedtls_ssl_config_defaults() didn’t fail?
Regards,

Mbed TLS Support
Ron

Hi Ron,
My this function ‘mbedtls_ssl_setup’ executing successfully now. Actually it was a problem with heap size memory, I increased heap memory size and now this function is working properly.

But now as I move further for initializing, I am again facing issue while tls handshaking. My

  1. TLS_Init function processed properly without error
  2. It tries to connect to mqtt broker i.e. mosquitto on my local machine using ‘mqtt_do_connect’ and it return ok
  3. It then goes for handshake using ‘mqtt_do_tls_handshake’; in this
    a. mbedtls_ssl_handshake-> mbedtls_ssl_handshake_step-> ssl_write_client_hello->
    mbedtls_ssl_write_record-> ssl_generate_random it executes this loops
    b. In ‘ssl_generate_random’ function: it executes ‘if( ( ret = ssl->conf->f_rng( ssl->conf-
    >p_rng, p, 28 ) ) != 0 )’
    (i) in this: mbedtls_ctr_drbg_random-> mbedtls_mutex_lock-> threading_mutex_fail
    THIS RETURNS ME ERROR: “MBEDTLS_ERR_THREADING_BAD_INPUT_DATA”
    i.e. -28 error code

What could be the problem and it’s relevant solution for this error?

Hi Ron,
I compared my TLS_init code with the code that I refered from internet. I checked that I have not included below lines of code:

if( ( ret = mbedtls_ctr_drbg_seed( &stctr_drbg, mbedtls_entropy_func, &stentropy,
(const unsigned char *) pers,
strlen(pers ) ) ) != 0 )
{
LWIP_DEBUGF(MQTT_APP_DEBUG_TRACE,( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ));
printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret );
return -1;
}
Now I added this and got error no. -52; so i debug my code and found that the same function i.e. mbedtls_mutex_lock-> threading_mutex_fail returns me an error.
The sequence of code flow is like:

mbedtls_ctr_drbg_seed-> mbedtls_ctr_drbg_reseed-> 0 != ctx->f_entropy( ctx->p_entropy, seed,
ctx->entropy_len ) -> mbedtls_entropy_func-> mbedtls_mutex_lock-> threading_mutex_fail and error “MBEDTLS_ERR_THREADING_BAD_INPUT_DATA”

kindly guide me through this.

Hi @urvishah
AS the errors imply, these are threading issues. Does your system support pthread? How is threading configured in your system for Mbed TLS?
AS you can see, MBEDTLS_ERR_THREADING_BAD_INPUT_DATA is returned in case MBEDTLS_THREADING_PTHREAD is defined if: ( mutex == NULL || ! mutex->is_valid ) however since you call mbedtls_entropy_init() so this shouldn’t be the case.

Is it possible you have defined MBEDTLS_THREADING_ALT but forgot to set your alternative implementation of threading with mbedtls_threading_set_alt()? In this case, the defult lock functionality will always fail with the error code you received because threading_mutex_fail is set by default.

Regards,
Ron

Hi @roneld01
In my project:
#define MBEDTLS_THREADING_ALT
//#define MBEDTLS_THREADING_PTHREAD

I have not used ‘mbedtls_threading_set_alt()’ yet. But I tried to implement it as:
/* Setup the thread callbacks */
mbedtls_threading_set_alt(threading_mutex_init_pthread,
threading_mutex_free_pthread, threading_mutex_lock_pthread,
threading_mutex_unlock_pthread);

It gives me below errors:
undefined first referenced
symbol in file


threading_mutex_free_pthread ./lwip_Mqtt.obj
threading_mutex_init_pthread ./lwip_Mqtt.obj
threading_mutex_lock_pthread ./lwip_Mqtt.obj
threading_mutex_unlock_pthread ./lwip_Mqtt.obj

In threading.c file, all these functions are declared under macro definition of:
#if defined(MBEDTLS_THREADING_PTHREAD)… and in my project this macro is undefined.

Then I tried to define this macro and compile my code again. It gives me 77 error in diferent mbedtls files:
gmake: *** [Third Party/mbedtls/library/ecp_curves.obj] Error 1
“C:\ti…\third_party\mbedtls\include\mbedtls\check_config.h”, line 616: fatal error #35: #error directive: “MBEDTLS_THREADING_ALT defined, but not all prerequisites”

Regards,
Urvi Shah

Hi @urvishah
If you define MBEDTLS_THREADING_PTHREAD, and your system has pthread, why do you need MBEDTLS_THREADING_ALT?

As you can see in the check_config.h file:

#if defined(MBEDTLS_THREADING_ALT)
#if !defined(MBEDTLS_THREADING_C) || defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_ALT defined, but not all prerequisites"
#endif
#define MBEDTLS_THREADING_IMPL
#endif

#if defined(MBEDTLS_THREADING_C) && !defined(MBEDTLS_THREADING_IMPL)
#error "MBEDTLS_THREADING_C defined, single threading implementation required"
#endif
#undef MBEDTLS_THREADING_IMPL

You can’t have both MBEDTLS_THREADING_PTHREAD and MBEDTLS_THREADING_ALT defined.
If your syustem doesn’t have pthread, you will need to supply your own threading implementation which is not pthread. If your system has pthread, you don’t need MBEDTLS_THREADING_ALT defined.
Regards

Hi @roneld01,

I am unaware of mbedtls library’s detail i.e. which macro is used for which purpose. I am trying to connect to my secure mqtt broker using mbedtls over lwip, and for that I have referred internet examples i.e. github. If you have any link which explains in short and simple way that how to use mbedtls with examples then do share it. I referred below links:

  1. https://mcuoneclipse.com/2017/04/17/tutorial-secure-tls-communication-with-mqtt-using-mbedtls-on-top-of-lwip/
    2.https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/MCUXpresso/FRDM-K64F/FRDM-K64F_lwip_lwip_mqtt_bm/source
  2. https://tls.mbed.org/module-level-design-ssl-tls

Now, I have commented “MBEDTLS_THREADING_ALT” macro and uncommented “MBEDTLS_THREADING_PTHREAD” macro in config.h file. So it gives me below errors:

  1. identifier “PTHREAD_MUTEX_INITIALIZER” is undefined threading.c
  2. invalid redeclaration of type name “mbedtls_threading_mutex_t” (declared at line 49 of “C:\ti…\third_party\mbedtls\include\mbedtls\threading.h”) external location: C:\ti…\third_party\mbedtls\ti\port\threading_alt.h C/C++ Problem

Hi @urvishah
in the Mbed TLS Knowledge base you will find several articles that will interest you.
I would suggest you start with the following:

As for the compilation errors you are receiving:

  1. PTHREAD_MUTEX_INITIALIZER is part of the pthread library. If you don’t have it, then you probably don’t have pthread in your system, and you should keep the previous configiuration of MBEDTLS_THREADING_ALT defined and MBEDTLS_THREADING_PTHREAD undefined. You should call mbedtls_threading_set_alt with the threading functions that are relevant for your platform.
  2. This error is because you already defined mbedtls_threading_mutex_t in your threading_alt.h file ( which is not part of the Mbed TLS release), and it collides with the default structure in Mbed TLS, when MBEDTLS_THREADING_PTHREAD is defined.
    Regards