Open
Description
Description of defect
I am trying to build a TLS server for an embedded device (nucleo-144 stm32f429).
I took as a guideline this example from mbedos (https://github.com/ARMmbed/mbed-os-example-tls/blob/master/tls-client/HelloHttpsClient.cpp) and readapted it with this example from mbedtls (https://github.com/ARMmbed/mbedtls/blob/development/programs/ssl/ssl_server.c).
The TCPSocket is established and works fine. However, during the handshake procedure, the device produces an error. I have ensured that the client is sending the "Client Hello" correctly and that the embedded device does not answer anymore after that.
I also ensured that if the embedded device works as a Client the device produces no faults.
++ MbedOS Fault Handler ++
FaultType: HardFault
Context:
R 0: 20008EB0
R 1: 2000D198
R 2: 00000005
R 3: FFFFFFFF
R 4: 2000D198
R 5: 00000000
R 6: 00000005
R 7: 00000005
R 8: 08041BB5
R 9: 08041C70
R 10: FFFF9800
R 11: 08041A40
R 12: 00000001
SP : 20005598
LR : 08007D9F
PC : FFFFFFFE
xPSR : 61000000
PSP : 20005530
MSP : 2002FFD0
CPUID: 410FC241
HFSR : 40000000
MMFSR: 00000001
BFSR : 00000000
UFSR : 00000000
DFSR : 00000000
AFSR : 00000000
Mode : Thread
Priv : Privileged
Stack: PSP
-- MbedOS Fault Handler --
++ MbedOS Error Info ++
Error Status: 0x80FF013D Code: 317 Module: 255
Error Message: Fault exception
Location: 0xFFFFFFFE
Error Value: 0x200001B0
Current Thread: main Id: 0x20008190 Entry: 0x80175D1 StackSize: 0x1000 StackMem: 0x200046D0 SP: 0x20005598
For more info, visit: https://mbed.com/s/error?error=0x80FF013D&tgt=NUCLEO_F439ZI
-- MbedOS Error Info --
= System will be rebooted due to a fatal error =
= Reboot count(=15) reached maximum, system will halt after rebooting =
Target(s) affected by this defect ?
Embedded device
Toolchain(s) (name and version) displaying this defect ?
n/a
What version of Mbed-os are you using (tag or sha) ?
mbed-os-6.14.0
What version(s) of tools are you using. List all that apply (E.g. mbed-cli)
n/a
How is this defect reproduced ?
int Server::run()
{
int ret;
/* Configure the TCPSocket */
if ((ret = configureTCPSocket()) != 0)
return ret;
/* Configure Mbed TLS structures */
if ((ret = configureTlsContexts()) != 0)
return ret;
/* Starts a server on a specific port */
SocketAddress saddr = SocketAddress("0.0.0.0");
saddr.set_port(4433);
mbedtls_printf("Bind on %s at port %u\n",
saddr.get_ip_address(), saddr.get_port());
if ((ret = socket.bind(saddr)) != NSAPI_ERROR_OK) {
mbedtls_printf("socket.bind() returned %d\n", ret);
return ret;
}
if ((ret = socket.listen()) != NSAPI_ERROR_OK) {
mbedtls_printf("socket.listen() returned %d\n", ret);
return ret;
}
accepted_socket = socket.accept();
SocketAddress test;
accepted_socket->getpeername(&test);
mbedtls_printf("getpeername: ip %s on port %u", test.get_ip_address(), test.get_port());
/* Start the TLS handshake */
mbedtls_printf("Starting the TLS handshake...\n");
do {
mbedtls_printf("handshake start\n");
ret = mbedtls_ssl_handshake(&ssl);
mbedtls_printf("handshake end %i\n",ret);
} while(ret != 0 &&
(ret == MBEDTLS_ERR_SSL_WANT_READ ||
ret == MBEDTLS_ERR_SSL_WANT_WRITE));
if (ret < 0) {
mbedtls_printf("mbedtls_ssl_handshake() returned -0x%04X\n", -ret);
return ret;
}
mbedtls_printf("Successfully completed the TLS handshake\n");
return 0;
}
int Server::configureTCPSocket()
{
int ret;
EthernetInterface eth;
eth.disconnect();
const SocketAddress eth_ip = SocketAddress("192.168.0.3");
const SocketAddress eth_netmask = SocketAddress("255.255.255.0");
const SocketAddress eth_gateway = SocketAddress("0.0.0.0");
eth.set_network(eth_ip, eth_netmask, eth_gateway);
ret = eth.connect();
SocketAddress a;
eth.get_ip_address(&a);
mbedtls_printf("eth address: %s\n", a.get_ip_address() ? a.get_ip_address() : "None");
if ((ret = socket.open(ð)) != NSAPI_ERROR_OK) {
mbedtls_printf("socket.open() returned %d\n", ret);
return ret;
}
return 0;
}
int Server::configureTlsContexts()
{
int ret;
ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
reinterpret_cast<const unsigned char *>(DRBG_PERSONALIZED_STR),
strlen(DRBG_PERSONALIZED_STR) + 1);
if (ret != 0) {
mbedtls_printf("mbedtls_ctr_drbg_seed() returned -0x%04X\n", -ret);
return ret;
}
ret = mbedtls_x509_crt_parse(&srvcert,
reinterpret_cast<const unsigned char *>(SRV_CERT),
strlen(SRV_CERT) + 1);
if (ret != 0) {
mbedtls_printf("mbedtls_x509_crt_parse() returned -0x%04X\n", -ret);
return ret;
}
ret = mbedtls_x509_crt_parse(&srvcert,
reinterpret_cast<const unsigned char *>(CA_CERT),
strlen(CA_CERT) + 1);
if (ret != 0) {
mbedtls_printf("mbedtls_x509_crt_parse() returned -0x%04X\n", -ret);
return ret;
}
ret = mbedtls_x509_crt_parse(&cacert,
reinterpret_cast<const unsigned char *>(CA_CERT),
strlen(CA_CERT) + 1);
if (ret != 0) {
mbedtls_printf("mbedtls_x509_crt_parse() returned -0x%04X\n", -ret);
return ret;
}
ret = mbedtls_pk_parse_key(&pvtkey,
reinterpret_cast<const unsigned char *>(SRV_PVT_KEY),
strlen(SRV_PVT_KEY) + 1, NULL, -1 );
if (ret != 0) {
mbedtls_printf("mbedtls_pk_parse_key() returned -0x%04X\n", -ret);
return ret;
}
ret = mbedtls_ssl_config_defaults(&ssl_conf, MBEDTLS_SSL_IS_SERVER,
MBEDTLS_SSL_TRANSPORT_STREAM,
MBEDTLS_SSL_PRESET_DEFAULT);
if (ret != 0) {
mbedtls_printf("mbedtls_ssl_config_defaults() returned -0x%04X\n",
-ret);
return ret;
}
mbedtls_ssl_conf_ca_chain(&ssl_conf, &cacert, NULL);
if( ( ret = mbedtls_ssl_conf_own_cert( &ssl_conf, &srvcert, &pvtkey ) ) != 0 )
{
mbedtls_printf( "mbedtls_ssl_conf_own_cert() returned %d\n", ret );
return ret;
}
mbedtls_ssl_conf_rng(&ssl_conf, mbedtls_ctr_drbg_random, &ctr_drbg);
/*
* It is possible to disable authentication by passing
* MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode()
*/
mbedtls_ssl_conf_authmode(&ssl_conf, MBEDTLS_SSL_VERIFY_REQUIRED);
/* Configure certificate verification function to clear time/date flags */
mbedtls_ssl_conf_verify(&ssl_conf, sslVerify, this);
#if HELLO_HTTPS_CLIENT_DEBUG_LEVEL > 0
mbedtls_ssl_conf_dbg(&ssl_conf, sslDebug, NULL);
mbedtls_debug_set_threshold(HELLO_HTTPS_CLIENT_DEBUG_LEVEL);
#endif /* HELLO_HTTPS_CLIENT_DEBUG_LEVEL > 0 */
if ((ret = mbedtls_ssl_setup( &ssl, &ssl_conf)) != 0) {
mbedtls_printf("mbedtls_ssl_setup() returned -0x%04X\n", -ret);
return ret;
}
mbedtls_ssl_set_bio(&ssl, static_cast<void *>(&accepted_socket), sslSend, sslRecv,
NULL);
return 0;
}
int Server::sslRecv(void *ctx, unsigned char *buf, size_t len)
{
int ret;
TCPSocket *s = static_cast<TCPSocket *>(ctx);
ret = s->recv(buf, len);
printf("buf recv %s\n", buf);
return ret;
}
int Server::sslSend(void *ctx, const unsigned char *buf, size_t len)
{
int ret;
TCPSocket *s = static_cast<TCPSocket *>(ctx);
ret = s->send(buf, len);
printf("buf send %s\n", buf);
return ret;
}