/* Initialize TLS library */ int init_tls_module(mbedtls_x509_crt *ca_certificates) { char version[16]; if (mbedtls_version_get_number() < 0x02000000) { mbedtls_version_get_string(version); fprintf(stderr, "This Hiawatha installation requires at least mbed TLS v2.0.0 and you have v%s.", version); return -1; } if (mbedtls_version_check_feature("MBEDTLS_THREADING_PTHREAD") != 0) { fprintf(stderr, "mbed TLS was compiled without the required MBEDTLS_THREADING_PTHREAD compiler flag.\n"); return -1; } #ifdef ENABLE_DEBUG mbedtls_debug_set_threshold(TLS_DEBUG_LEVEL); #endif /* Entropy settings */ mbedtls_entropy_init(&entropy); mbedtls_ctr_drbg_init(&ctr_drbg); if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (unsigned char*)"Hiawatha_RND", 10) != 0) { return -1; } mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF); /* Cache settings */ mbedtls_ssl_cache_init(&cache); mbedtls_ssl_cache_set_max_entries(&cache, 100); /* Client SSL configuratiomn */ mbedtls_ssl_config_init(&client_config); if (mbedtls_ssl_config_defaults(&client_config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) { return -1; } mbedtls_ssl_conf_min_version(&client_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1); mbedtls_ssl_conf_renegotiation(&client_config, MBEDTLS_SSL_RENEGOTIATION_DISABLED); mbedtls_ssl_conf_rng(&client_config, tls_random, &ctr_drbg); #ifdef ENABLE_DEBUG mbedtls_ssl_conf_dbg(&client_config, tls_debug, &client_config); #endif if (ca_certificates == NULL) { mbedtls_ssl_conf_authmode(&client_config, MBEDTLS_SSL_VERIFY_NONE); } else { mbedtls_ssl_conf_authmode(&client_config, MBEDTLS_SSL_VERIFY_REQUIRED); mbedtls_ssl_conf_ca_chain(&client_config, ca_certificates, NULL); } if (pthread_mutex_init(&random_mutex, NULL) != 0) { return -1; } else if (pthread_mutex_init(&cache_mutex, NULL) != 0) { return -1; } return 0; }
/** Create new TLS configuration * ATTENTION: Server certificate and private key have to be added outside this function! */ static struct altcp_tls_config * altcp_tls_create_config(int is_server, int have_cert, int have_pkey, int have_ca) { size_t sz; int ret; struct altcp_tls_config *conf; mbedtls_x509_crt *mem; if (TCP_WND < MBEDTLS_SSL_MAX_CONTENT_LEN) { LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG|LWIP_DBG_LEVEL_SERIOUS, ("altcp_tls: TCP_WND is smaller than the RX decrypion buffer, connection RX might stall!\n")); } altcp_mbedtls_mem_init(); sz = sizeof(struct altcp_tls_config); if (have_cert) { sz += sizeof(mbedtls_x509_crt); } if (have_ca) { sz += sizeof(mbedtls_x509_crt); } if (have_pkey) { sz += sizeof(mbedtls_pk_context); } conf = (struct altcp_tls_config *)altcp_mbedtls_alloc_config(sz); if (conf == NULL) { return NULL; } mem = (mbedtls_x509_crt *)(conf + 1); if (have_cert) { conf->cert = mem; mem++; } if (have_ca) { conf->ca = mem; mem++; } if (have_pkey) { conf->pkey = (mbedtls_pk_context *)mem; } mbedtls_ssl_config_init(&conf->conf); mbedtls_entropy_init(&conf->entropy); mbedtls_ctr_drbg_init(&conf->ctr_drbg); /* Seed the RNG */ ret = mbedtls_ctr_drbg_seed(&conf->ctr_drbg, ALTCP_MBEDTLS_RNG_FN, &conf->entropy, ALTCP_MBEDTLS_ENTROPY_PTR, ALTCP_MBEDTLS_ENTROPY_LEN); if (ret != 0) { LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ctr_drbg_seed failed: %d\n", ret)); altcp_mbedtls_free_config(conf); return NULL; } /* Setup ssl context (@todo: what's different for a client here? -> might better be done on listen/connect) */ ret = mbedtls_ssl_config_defaults(&conf->conf, is_server ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if (ret != 0) { LWIP_DEBUGF(ALTCP_MBEDTLS_DEBUG, ("mbedtls_ssl_config_defaults failed: %d\n", ret)); altcp_mbedtls_free_config(conf); return NULL; } mbedtls_ssl_conf_authmode(&conf->conf, MBEDTLS_SSL_VERIFY_OPTIONAL); mbedtls_ssl_conf_rng(&conf->conf, mbedtls_ctr_drbg_random, &conf->ctr_drbg); #if ALTCP_MBEDTLS_DEBUG != LWIP_DBG_OFF mbedtls_ssl_conf_dbg(&conf->conf, altcp_mbedtls_debug, stdout); #endif #if defined(MBEDTLS_SSL_CACHE_C) && ALTCP_MBEDTLS_SESSION_CACHE_TIMEOUT_SECONDS mbedtls_ssl_conf_session_cache(&conf->conf, &conf->cache, mbedtls_ssl_cache_get, mbedtls_ssl_cache_set); mbedtls_ssl_cache_set_timeout(&conf->cache, 30); mbedtls_ssl_cache_set_max_entries(&conf->cache, 30); #endif return conf; }