Hello,
First of all thanks for providing mbedTLS.
I am trying to use it with bare metal STM32 Nucleo-F401RE and a SIM800 GSM modem for HTTPS GET/POST.
I will try to do a quick sum-up of where I am and where I am stuck. Also, I hope that this post helps others in similar position.
- I am trying to make an HTTPS GET here.
- So far, I am able to create an SSL context, and parse the public key, as well as root CA like so (please ignore the custom ugly prints. Also, the code is based on this example)
int ret, flags, len; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_pk_context pk; mbedtls_x509_crt cacert; mbedtls_net_context server_fd; mbedtls_ssl_init(&ssl); mbedtls_pk_init(&pk); mbedtls_x509_crt_init(&cacert); mbedtls_ssl_config_init(&conf); custom_print("Parsing public key...\r\n"); ret = mbedtls_pk_parse_public_key(&pk, myPubKey, myPubKeyLen); if (ret < 0) { sprintf(buf2, "mbedtls_pk_parse_public_key returned -0x%x\n\n", -ret); custom_print(buf2); memset(buf2, 0, sizeof(buf2)); } custom_print("pubkey OK"); custom_print("Parsing CA root...\r\n"); ret = mbedtls_x509_crt_parse(&cacert, myCert, myCertlen + 1); if (ret < 0) { sprintf(buf2, "mbedtls_x509_crt_parse returned -0x%x\n\n", -ret); custom_print(buf2); memset(buf2, 0, sizeof(buf2)); } custom_print("CA OK"); custom_print("Setting hostname for TLS session...\r\n"); /* Hostname set here should match CN in server certificate */ if ((ret = mbedtls_ssl_set_hostname(&ssl, WEB_SERVER)) != 0) { sprintf(buf2, "mbedtls_ssl_set_hostname returned -0x%x", -ret); custom_print(buf2); memset(buf2, 0, sizeof(buf2)); } custom_print("hostname OK"); custom_print("Setting up the SSL/TLS structure..."); if ((ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { sprintf(buf2, "mbedtls_ssl_config_defaults returned %d", -ret); custom_print(buf2); memset(buf2, 0, sizeof(buf2)); } custom_print("SSL/TLS structure OK"); custom_print("Setting up SSL..."); mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); /* bad bad */ mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL); if ((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) { sprintf(buf2, "mbedtls_ssl_setup returned -0x%x\n\n", -ret); custom_print(buf2); memset(buf2, 0, sizeof(buf2)); } custom_print("SSL setup OK");
So far, so good. At this point, I have already opened a TCP connection to the server initiated and waiting for data in my UART port via the appropriate AT commands (I have an IP, and I can perform requests OK), therefore I need to provide the custom functions for reading and writing from/to UART, like:
mbedtls_ssl_set_bio(&ssl, &server_fd, UART_ssl_bridge_write(&server_fd, ssl_o_buffer, sizeof(ssl_o_buffer)), UART_ssl_bridge_read(&server_fd, ssl_i_buffer, sizeof(ssl_i_buffer)), NULL);
The corresponding crude prototypes are the following:
size_t UART_ssl_bridge_write(void *ctx, const unsigned char *buf, size_t len) {
HAL_UART_Transmit_DMA(&huart6, buf, len); HAL_UART_Transmit(&huart2, buf, len, 1000); while (!UART6txComple) {/* wait for cmd to go, txCallbackCplt */ HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5); HAL_Delay(100); } return len;
}
size_t UART_ssl_bridge_read(void *ctx, const unsigned char *buf, size_t len) {
HAL_UART_DMAStop(&huart6); memset(buf, '\0', sizeof(buf)); HAL_UART_Receive(&huart6, buf, len, 1000); return len - strlen(buf);
}
Both are implemented in a blocking manner. Then I call this:
custom_print("Initialize handshake"); while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) { if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) { sprintf(buf2, "mbedtls_ssl_handshake returned -0x%x", -ret); custom_print(buf2); memset(buf2, 0, sizeof(buf2)); goto exit; } }
And I get -0x7080 which is pretty bad, because even If i don’t initiate any connection from the modem I get the same error, meaning that I am missing something in between.
What I know I am missing is an entropy source, because my hardware does not have one. So I implemented a function to gather measurements from the internal ADC temp sensor; not so secure, but for my prototype it is enough.
uint32_t get_random_number(int timesToPoll) {
ADC->CCR |= ADC_CCR_TSVREFE; ADC->CCR &= ~ADC_CCR_VBATE; sConfig.Channel = ADC_CHANNEL_1; HAL_ADC_ConfigChannel(&hadc1, &sConfig); for (int i = 0; i < timesToPoll; i++) { HAL_ADC_Start(&hadc1); if (HAL_ADC_PollForConversion(&hadc1, 5) == HAL_OK) adcVal1 += HAL_ADC_GetValue(&hadc1); HAL_Delay(50); } return adcVal1; /* returns ADC_CHANNEL_1 value */
}
Questions:
- Although I am going through documentation on how to add an entropy source, I am obviously either too tired or I can’t grasp on how to add that function to the entropy pool and make use of it.
- What am I missing and instead of getting any response from the server, I am getting the same response either with or without my module connected to it? I even tried to go PPPoS to leverage sockets and so on but to be honest it is discouraging from scratch, at least for my level. I am currently not looking at full mbed OS implementation, which has a lot of functionality, but I cannot integrate with the rest of my code.
I also provide my config file for reference:
#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H
/* System support */
#define MBEDTLS_HAVE_ASM#define MBEDTLS_TEST_NULL_ENTROPY
#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_NO_PLATFORM_ENTROPY#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_SSL_PROTO_SSL3
#define MBEDTLS_SSL_PROTO_TLS1
#define MBEDTLS_SSL_PROTO_TLS1_1
#define MBEDTLS_SSL_PROTO_TLS1_2/* mbed TLS feature support */
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_CIPHER_PADDING_PKCS7
#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
#define MBEDTLS_ECP_NIST_OPTIM
#define MBEDTLS_ECDSA_DETERMINISTIC
#define MBEDTLS_PK_RSA_ALT_SUPPORT
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_PKCS1_V21
#define MBEDTLS_SELF_TEST
#define MBEDTLS_VERSION_FEATURES
#define MBEDTLS_X509_CHECK_KEY_USAGE
#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE/* mbed TLS modules */
#define MBEDTLS_AES_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C
#define MBEDTLS_BASE64_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C
#define MBEDTLS_ERROR_C
#define MBEDTLS_GCM_C
#define MBEDTLS_HMAC_DRBG_C
#define MBEDTLS_MD_C
#define MBEDTLS_OID_C
#define MBEDTLS_PEM_PARSE_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C
#define MBEDTLS_PK_WRITE_C
#define MBEDTLS_PLATFORM_C
#define MBEDTLS_RSA_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C
#define MBEDTLS_VERSION_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_CRL_PARSE_C
#define MBEDTLS_CMAC_C
#define MBEDTLS_SSL_CACHE_C#define MBEDTLS_MD5_C
#define MBEDTLS_SHA1_C
#define MBEDTLS_CIPHER_C
#define MBEDTLS_MD_C
/* Miscellaneous options */
#define MBEDTLS_AES_ROM_TABLES#include “check_config.h”
#endif /* MBEDTLS_CONFIG_H */
Any input would be really appreciated. Keep up the good work.
Dimitris
FAST EDIT
I was browsing the forum and came across this. I will review support’s responses because it looks like most of the issues there are similar to mine and PEBCAK. In the meantime, If you have any comments on my post, please feel free to provide any feedback. Thanks again.