MbedTLS Handshake failing between client & server (v 3.4.0)





Hello,
I’m trying to develop an application using MbedTLS SSL libraries that encrypts data exchange between client & server using PSK based TLS 1.2.

Turns out that client side is crashing while trying to send the change cipher spec message during TLS handshake.

Crash:
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Call stack:
(mbedtls_ssl_write_handshake_msg_ext.cfi+1752) (BuildId: 063bc231b105d66ece7418b0a7ac9de4)
(mbedtls_ssl_write_change_cipher_spec.cfi+124) (BuildId: 063bc231b105d66ece7418b0a7ac9de4)
(mbedtls_ssl_handshake_client_step.cfi+1912) (BuildId: 063bc231b105d66ece7418b0a7ac9de4)
(mbedtls_ssl_handshake_step.cfi+400) (BuildId: 063bc231b105d66ece7418b0a7ac9de4)
(mbedtls_ssl_handshake.cfi+108) (BuildId: 063bc231b105d66ece7418b0a7ac9de4)

Server times out waiting for the change cipher spec message from the client.

It is crashing on line number 4 in the code below:

1 int mbedtls_ssl_write_handshake_msg( mbedtls_ssl_context *ssl )
2 {
3 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
4 const size_t hs_len = ssl->out_msglen - 4;
5 const unsigned char hs_type = ssl->out_msg[0];
6
7 MBEDTLS_SSL_DEBUG_MSG( 2, ( “=> write handshake message” ) );

ssl->state is MBEDTLS_SSL_CLIENT_FINISHED and ssl->out_msglen is 1 which is making hs_len as -3.
Is that causing the crash?

Any pointers on missing API calls/discrepancies in the order in which the API calls were made would be greatly appreciated.

I’m sharing the high-level client & server code below. I’ve also attached MbedTLS debug logs for the same.

Client code:

#define SERVER_PORT “50000”
#define SERVER_NAME “192.168.142.38”

#define DFL_FORCE_CIPHER 0x8c
#define DFL_PSK_IDENTITY “Client1”

struct options
{
const char *psk_identity;
int force_ciphersuite[2];
} opt;

const unsigned char psk = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
};

static void my_debug_client( void *ctx, int level, const char *file, int line, const char *str )
{
((void) level);
( “%s:%s:%04d: %s”, func,file, line, str );
fflush( (FILE *) ctx );
}

static void my_debug_server( void *ctx, int level, const char *file, int line, const char *str )
{
((void) level);
(“%s:%s:%04d: %s”,func, file, line, str );
fflush( (FILE *) ctx );
}

int psk_callback( void *p_info, mbedtls_ssl_context *ssl, const unsigned char *name, size_t name_len )
{
( " Inside PSK callback \n" );
psk_entry *cur = (psk_entry *) p_info;
( " name:%s\n", name );
return( mbedtls_ssl_set_hs_psk( ssl, (const unsigned char *) psk, sizeof(psk) ) );
}

main() {

mbedtls_platform_setup(NULL));

mbedtls_net_context server_fd;
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;

const char *pers = “ssl_client1”;

mbedtls_net_init( &server_fd );
mbedtls_ssl_init( &ssl );
mbedtls_ssl_config_init( &conf );
mbedtls_ctr_drbg_init( &ctr_drbg );
( “Seeding the random number generator” );
mbedtls_entropy_init( &entropy );
mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) ) ;
( " ok\n" );
( “Connecting to tcp/%s/%s”, SERVER_NAME, SERVER_PORT );
mbedtls_net_connect( &server_fd, SERVER_NAME,SERVER_PORT, MBEDTLS_NET_PROTO_TCP );
( " ok\n" );
( “Setting up the SSL/TLS structure” );
mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT );
( " ok\n" );
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE );
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
mbedtls_debug_set_threshold(5);
mbedtls_ssl_conf_dbg( &conf, my_debug_client, stdout );
mbedtls_ssl_setup( &ssl, &conf );
mbedtls_ssl_set_hostname( &ssl, SERVER_NAME );
mbedtls_ssl_set_bio( &ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
mbedtls_ssl_conf_min_tls_version( &conf, MBEDTLS_SSL_VERSION_TLS1_2 );
mbedtls_ssl_conf_max_tls_version( &conf, MBEDTLS_SSL_VERSION_TLS1_2);
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
opt.psk_identity = DFL_PSK_IDENTITY;
mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
mbedtls_ssl_conf_psk(&conf, (const unsigned char *) psk, sizeof(psk),(const unsigned char *) opt.psk_identity, strlen( opt.psk_identity ) );
( “Performing the SSL/TLS handshake” );
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
{
//
}
( " ok\n" );
}

Server code:

main() {

int ret = 1, len;
unsigned char buf[1024];
psk_entry *psk_info = NULL;

mbedtls_platform_setup(NULL));

mbedtls_net_context listen_fd, client_fd;
const char *pers = “ssl_server”;

mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ssl_context ssl;
mbedtls_ssl_config conf;

mbedtls_net_init( &listen_fd );
mbedtls_net_init( &client_fd );
mbedtls_ssl_init( &ssl );
mbedtls_ssl_config_init( &conf );
mbedtls_entropy_init( &entropy );
mbedtls_ctr_drbg_init( &ctr_drbg );

( “Seeding the random number generator” );
mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, strlen( pers ) );
( " ok\n" );
( “Bind on socket” );
mbedtls_net_bind( &listen_fd, NULL, “50000”, MBEDTLS_NET_PROTO_TCP );
( " ok\n" );
( “Setting up the SSL data” );
mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
mbedtls_ssl_conf_rng( &conf, mbedtls_ctr_drbg_random, &ctr_drbg );
mbedtls_debug_set_threshold(5);
mbedtls_ssl_conf_dbg( &conf, my_debug_server, stdout );
mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE );
mbedtls_ssl_setup( &ssl, &conf );
( " ok\n" );
mbedtls_ssl_set_bio( &ssl, &client_fd, mbedtls_net_send, mbedtls_net_recv, NULL );
( " ok\n" );
( “Waiting for a remote connection” );
mbedtls_net_accept( &listen_fd, &client_fd, NULL, 0, NULL );
opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
opt.psk_identity = DFL_PSK_IDENTITY;
( “Setting up TLS version” );
mbedtls_ssl_conf_min_tls_version( &conf, MBEDTLS_SSL_VERSION_TLS1_2);
mbedtls_ssl_conf_max_tls_version( &conf, MBEDTLS_SSL_VERSION_TLS1_2);
( “Configuring ciphersuites” );
mbedtls_ssl_conf_ciphersuites( &conf, opt.force_ciphersuite );
( “Setting up pre-shared key” );
mbedtls_ssl_conf_psk(&conf, (const unsigned char *) psk, sizeof(psk), (const unsigned char *) opt.psk_identity, strlen( opt.psk_identity ) );
mbedtls_ssl_conf_psk_cb( &conf, psk_callback, psk_info );
( “Performing the SSL/TLS handshake” );
while( ( ret = mbedtls_ssl_handshake( &ssl ) ) != 0 )
{
if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
{
( " failed\n ! mbedtls_ssl_handshake returned %d\n\n", ret );
(“Last error was: %d - %s\n\n”, ret, error_buf );
}
}
( " ok\n" );
}

Thanks,
Sai Gosamsetti.