Add initial mbedTLS and HTTPS example project (using howsmyssl.com JSON API)
mbedTLS version 2.1.0 (current stable) Has some known issues/hacks: * Entropy source not hooked in at all * Linker script has a messy hack in it to store some (not all) data in irom
This commit is contained in:
		
							parent
							
								
									f230fbcd65
								
							
						
					
					
						commit
						1b22cc088e
					
				
					 10 changed files with 3455 additions and 58 deletions
				
			
		
							
								
								
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -5,3 +5,6 @@
 | 
			
		|||
	path = axtls/axtls
 | 
			
		||||
	url = https://github.com/SuperHouse/axtls.git
 | 
			
		||||
 | 
			
		||||
[submodule "extras/mbedtls/mbedtls"]
 | 
			
		||||
	path = extras/mbedtls/mbedtls
 | 
			
		||||
	url = https://github.com/ARMmbed/mbedtls.git
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										4
									
								
								examples/http_get_mbedtls/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								examples/http_get_mbedtls/Makefile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,4 @@
 | 
			
		|||
PROGRAM=http_get_mbedtls
 | 
			
		||||
COMPONENTS = FreeRTOS lwip core extras/mbedtls
 | 
			
		||||
 | 
			
		||||
include ../../common.mk
 | 
			
		||||
							
								
								
									
										347
									
								
								examples/http_get_mbedtls/http_get_mbedtls.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								examples/http_get_mbedtls/http_get_mbedtls.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,347 @@
 | 
			
		|||
/* http_get_mbedtls - HTTPS version of the http_get example, using mbed TLS.
 | 
			
		||||
 *
 | 
			
		||||
 * Retrieves a JSON response from the howsmyssl.com API via HTTPS over TLS v1.2.
 | 
			
		||||
 *
 | 
			
		||||
 * Validates the server's certificate using the root CA loaded (in PEM format) in cert.c.
 | 
			
		||||
 *
 | 
			
		||||
 * Adapted from the ssl_client1 example in mbedtls.
 | 
			
		||||
 *
 | 
			
		||||
 * Original Copyright (C) 2006-2015, ARM Limited, All Rights Reserved, Apache 2.0 License.
 | 
			
		||||
 * Additions Copyright (C) 2015 Angus Gratton, Apache 2.0 License.
 | 
			
		||||
 */
 | 
			
		||||
#include "espressif/esp_common.h"
 | 
			
		||||
#include "espressif/sdk_private.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "FreeRTOS.h"
 | 
			
		||||
#include "task.h"
 | 
			
		||||
 | 
			
		||||
#include "lwip/err.h"
 | 
			
		||||
#include "lwip/sockets.h"
 | 
			
		||||
#include "lwip/sys.h"
 | 
			
		||||
#include "lwip/netdb.h"
 | 
			
		||||
#include "lwip/dns.h"
 | 
			
		||||
#include "lwip/api.h"
 | 
			
		||||
 | 
			
		||||
#include "ssid_config.h"
 | 
			
		||||
 | 
			
		||||
/* mbedtls/config.h MUST appear before all other mbedtls headers, or
 | 
			
		||||
   you'll get the default config.
 | 
			
		||||
 | 
			
		||||
   (Although mostly that isn't a big problem, you just might get
 | 
			
		||||
   errors at link time if functions don't exist.) */
 | 
			
		||||
#include "mbedtls/config.h"
 | 
			
		||||
 | 
			
		||||
#include "mbedtls/net.h"
 | 
			
		||||
#include "mbedtls/debug.h"
 | 
			
		||||
#include "mbedtls/ssl.h"
 | 
			
		||||
#include "mbedtls/entropy.h"
 | 
			
		||||
#include "mbedtls/ctr_drbg.h"
 | 
			
		||||
#include "mbedtls/error.h"
 | 
			
		||||
#include "mbedtls/certs.h"
 | 
			
		||||
 | 
			
		||||
#define WEB_SERVER "howsmyssl.com"
 | 
			
		||||
#define WEB_PORT "443"
 | 
			
		||||
#define WEB_URL "https://www.howsmyssl.com/a/check"
 | 
			
		||||
 | 
			
		||||
#define GET_REQUEST "GET "WEB_URL" HTTP/1.1\n\n"
 | 
			
		||||
 | 
			
		||||
/* Root cert for howsmyssl.com, stored in cert.c */
 | 
			
		||||
extern const char *server_root_cert;
 | 
			
		||||
 | 
			
		||||
/* MBEDTLS_DEBUG_C disabled by default to save substantial bloating of
 | 
			
		||||
 * firmware, define it in
 | 
			
		||||
 * examples/http_get_mbedtls/include/mbedtls/config.h if you'd like
 | 
			
		||||
 * debugging output.
 | 
			
		||||
 */
 | 
			
		||||
#ifdef MBEDTLS_DEBUG_C
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Increase this value to see more TLS debug details,
 | 
			
		||||
   0 prints nothing, 1 will print any errors, 4 will print _everything_
 | 
			
		||||
*/
 | 
			
		||||
#define DEBUG_LEVEL 4
 | 
			
		||||
 | 
			
		||||
static void my_debug(void *ctx, int level,
 | 
			
		||||
                     const char *file, int line,
 | 
			
		||||
                     const char *str)
 | 
			
		||||
{
 | 
			
		||||
    ((void) level);
 | 
			
		||||
 | 
			
		||||
    /* Shorten 'file' from the whole file path to just the filename
 | 
			
		||||
 | 
			
		||||
       This is a bit wasteful because the macros are compiled in with
 | 
			
		||||
       the full _FILE_ path in each case, so the firmware is bloated out
 | 
			
		||||
       by a few kb. But there's not a lot we can do about it...
 | 
			
		||||
    */
 | 
			
		||||
    char *file_sep = rindex(file, '/');
 | 
			
		||||
    if(file_sep)
 | 
			
		||||
        file = file_sep+1;
 | 
			
		||||
 | 
			
		||||
    printf("%s:%04d: %s", file, line, str);
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void http_get_task(void *pvParameters)
 | 
			
		||||
{
 | 
			
		||||
    int successes = 0, failures = 0, ret;
 | 
			
		||||
    printf("HTTP get task starting...\n");
 | 
			
		||||
 | 
			
		||||
    uint32_t flags;
 | 
			
		||||
    unsigned char buf[1024];
 | 
			
		||||
    const char *pers = "ssl_client1";
 | 
			
		||||
 | 
			
		||||
    mbedtls_entropy_context entropy;
 | 
			
		||||
    mbedtls_ctr_drbg_context ctr_drbg;
 | 
			
		||||
    mbedtls_ssl_context ssl;
 | 
			
		||||
    mbedtls_x509_crt cacert;
 | 
			
		||||
    mbedtls_ssl_config conf;
 | 
			
		||||
    mbedtls_net_context server_fd;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 0. Initialize the RNG and the session data
 | 
			
		||||
     */
 | 
			
		||||
    mbedtls_ssl_init(&ssl);
 | 
			
		||||
    mbedtls_x509_crt_init(&cacert);
 | 
			
		||||
    mbedtls_ctr_drbg_init(&ctr_drbg);
 | 
			
		||||
    printf("\n  . Seeding the random number generator...");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
 | 
			
		||||
    mbedtls_ssl_config_init(&conf);
 | 
			
		||||
 | 
			
		||||
    mbedtls_entropy_init(&entropy);
 | 
			
		||||
    if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
 | 
			
		||||
                                    (const unsigned char *) pers,
 | 
			
		||||
                                    strlen(pers))) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret);
 | 
			
		||||
        while(1) {} /* todo: replace with abort() */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 0. Initialize certificates
 | 
			
		||||
     */
 | 
			
		||||
    printf("  . Loading the CA root certificate ...");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
 | 
			
		||||
    ret = mbedtls_x509_crt_parse(&cacert, (uint8_t*)server_root_cert, strlen(server_root_cert)+1);
 | 
			
		||||
    if(ret < 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  !  mbedtls_x509_crt_parse returned -0x%x\n\n", -ret);
 | 
			
		||||
        while(1) {} /* todo: replace with abort() */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf(" ok (%d skipped)\n", ret);
 | 
			
		||||
 | 
			
		||||
    /* Hostname set here should match CN in server certificate */
 | 
			
		||||
    if((ret = mbedtls_ssl_set_hostname(&ssl, WEB_SERVER)) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  ! mbedtls_ssl_set_hostname returned %d\n\n", ret);
 | 
			
		||||
        while(1) {} /* todo: replace with abort() */
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 2. Setup stuff
 | 
			
		||||
     */
 | 
			
		||||
    printf("  . Setting up the SSL/TLS structure...");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
 | 
			
		||||
    if((ret = mbedtls_ssl_config_defaults(&conf,
 | 
			
		||||
                                          MBEDTLS_SSL_IS_CLIENT,
 | 
			
		||||
                                          MBEDTLS_SSL_TRANSPORT_STREAM,
 | 
			
		||||
                                          MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  ! mbedtls_ssl_config_defaults returned %d\n\n", ret);
 | 
			
		||||
        goto exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
    /* OPTIONAL is not optimal for security, in this example it will print
 | 
			
		||||
       a warning if CA verification fails but it will continue to connect.
 | 
			
		||||
    */
 | 
			
		||||
    mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL);
 | 
			
		||||
    mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
 | 
			
		||||
    mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
 | 
			
		||||
#ifdef MBEDTLS_DEBUG_C
 | 
			
		||||
    mbedtls_debug_set_threshold(DEBUG_LEVEL);
 | 
			
		||||
    mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" failed\n  ! mbedtls_ssl_setup returned %d\n\n", ret);
 | 
			
		||||
        goto exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Wait until we can resolve the DNS for the server, as an indication
 | 
			
		||||
       our network is probably working...
 | 
			
		||||
    */
 | 
			
		||||
    printf("Waiting for server DNS to resolve... ");
 | 
			
		||||
    fflush(stdout);
 | 
			
		||||
    err_t dns_err;
 | 
			
		||||
    ip_addr_t host_ip;
 | 
			
		||||
    do {
 | 
			
		||||
        vTaskDelay(500 / portTICK_RATE_MS);
 | 
			
		||||
        dns_err = netconn_gethostbyname(WEB_SERVER, &host_ip);
 | 
			
		||||
    } while(dns_err != ERR_OK);
 | 
			
		||||
    printf("done.\n");
 | 
			
		||||
 | 
			
		||||
    while(1) {
 | 
			
		||||
        mbedtls_net_init(&server_fd);
 | 
			
		||||
        printf("top of loop, free heap = %u\n", xPortGetFreeHeapSize());
 | 
			
		||||
        /*
 | 
			
		||||
         * 1. Start the connection
 | 
			
		||||
         */
 | 
			
		||||
        printf("  . Connecting to %s:%s...", WEB_SERVER, WEB_PORT);
 | 
			
		||||
        fflush(stdout);
 | 
			
		||||
 | 
			
		||||
        if((ret = mbedtls_net_connect(&server_fd, WEB_SERVER,
 | 
			
		||||
                                      WEB_PORT, MBEDTLS_NET_PROTO_TCP)) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            printf(" failed\n  ! mbedtls_net_connect returned %d\n\n", ret);
 | 
			
		||||
            goto exit;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
        mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, NULL);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * 4. Handshake
 | 
			
		||||
         */
 | 
			
		||||
        printf("  . Performing the SSL/TLS handshake...");
 | 
			
		||||
        fflush(stdout);
 | 
			
		||||
 | 
			
		||||
        while((ret = mbedtls_ssl_handshake(&ssl)) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
 | 
			
		||||
            {
 | 
			
		||||
                printf(" failed\n  ! mbedtls_ssl_handshake returned -0x%x\n\n", -ret);
 | 
			
		||||
                goto exit;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * 5. Verify the server certificate
 | 
			
		||||
         */
 | 
			
		||||
        printf("  . Verifying peer X.509 certificate...");
 | 
			
		||||
 | 
			
		||||
        /* In real life, we probably want to bail out when ret != 0 */
 | 
			
		||||
        if((flags = mbedtls_ssl_get_verify_result(&ssl)) != 0)
 | 
			
		||||
        {
 | 
			
		||||
            char vrfy_buf[512];
 | 
			
		||||
 | 
			
		||||
            printf(" failed\n");
 | 
			
		||||
 | 
			
		||||
            mbedtls_x509_crt_verify_info(vrfy_buf, sizeof(vrfy_buf), "  ! ", flags);
 | 
			
		||||
 | 
			
		||||
            printf("%s\n", vrfy_buf);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
            printf(" ok\n");
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * 3. Write the GET request
 | 
			
		||||
         */
 | 
			
		||||
        printf("  > Write to server:");
 | 
			
		||||
        fflush(stdout);
 | 
			
		||||
 | 
			
		||||
        int len = sprintf((char *) buf, GET_REQUEST);
 | 
			
		||||
 | 
			
		||||
        while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0)
 | 
			
		||||
        {
 | 
			
		||||
            if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
 | 
			
		||||
            {
 | 
			
		||||
                printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
 | 
			
		||||
                goto exit;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        len = ret;
 | 
			
		||||
        printf(" %d bytes written\n\n%s", len, (char *) buf);
 | 
			
		||||
 | 
			
		||||
        /*
 | 
			
		||||
         * 7. Read the HTTP response
 | 
			
		||||
         */
 | 
			
		||||
        printf("  < Read from server:");
 | 
			
		||||
        fflush(stdout);
 | 
			
		||||
 | 
			
		||||
        do
 | 
			
		||||
        {
 | 
			
		||||
            len = sizeof(buf) - 1;
 | 
			
		||||
            memset(buf, 0, sizeof(buf));
 | 
			
		||||
            ret = mbedtls_ssl_read(&ssl, buf, len);
 | 
			
		||||
 | 
			
		||||
            if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE)
 | 
			
		||||
                continue;
 | 
			
		||||
 | 
			
		||||
            if(ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) {
 | 
			
		||||
                ret = 0;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(ret < 0)
 | 
			
		||||
            {
 | 
			
		||||
                printf("failed\n  ! mbedtls_ssl_read returned %d\n\n", ret);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(ret == 0)
 | 
			
		||||
            {
 | 
			
		||||
                printf("\n\nEOF\n\n");
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            len = ret;
 | 
			
		||||
            printf(" %d bytes read\n\n%s", len, (char *) buf);
 | 
			
		||||
        } while(1);
 | 
			
		||||
 | 
			
		||||
        mbedtls_ssl_close_notify(&ssl);
 | 
			
		||||
 | 
			
		||||
    exit:
 | 
			
		||||
        mbedtls_ssl_session_reset(&ssl);
 | 
			
		||||
        mbedtls_net_free(&server_fd);
 | 
			
		||||
 | 
			
		||||
        if(ret != 0)
 | 
			
		||||
        {
 | 
			
		||||
            char error_buf[100];
 | 
			
		||||
            mbedtls_strerror(ret, error_buf, 100);
 | 
			
		||||
            printf("\n\nLast error was: %d - %s\n\n", ret, error_buf);
 | 
			
		||||
            failures++;
 | 
			
		||||
        } else {
 | 
			
		||||
            successes++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        printf("\n\nsuccesses = %d failures = %d\n", successes, failures);
 | 
			
		||||
        for(int countdown = successes ? 10 : 5; countdown >= 0; countdown--) {
 | 
			
		||||
            printf("%d... ", countdown);
 | 
			
		||||
            fflush(stdout);
 | 
			
		||||
            vTaskDelay(1000 / portTICK_RATE_MS);
 | 
			
		||||
        }
 | 
			
		||||
        printf("\nStarting again!\n");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void user_init(void)
 | 
			
		||||
{
 | 
			
		||||
    sdk_uart_div_modify(0, UART_CLK_FREQ / 115200);
 | 
			
		||||
    printf("SDK version:%s\n", sdk_system_get_sdk_version());
 | 
			
		||||
 | 
			
		||||
    struct sdk_station_config config = {
 | 
			
		||||
        .ssid = WIFI_SSID,
 | 
			
		||||
        .password = WIFI_PASS,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /* required to call wifi_set_opmode before station_set_config */
 | 
			
		||||
    sdk_wifi_set_opmode(STATION_MODE);
 | 
			
		||||
    sdk_wifi_station_set_config(&config);
 | 
			
		||||
 | 
			
		||||
    xTaskCreate(&http_get_task, (signed char *)"get_task", 2048, NULL, 2, NULL);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										27
									
								
								examples/http_get_mbedtls/include/mbedtls/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								examples/http_get_mbedtls/include/mbedtls/config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,27 @@
 | 
			
		|||
/* Special mbedTLS config file for http_get_mbedtls example,
 | 
			
		||||
   overrides supported cipher suite list.
 | 
			
		||||
 | 
			
		||||
   Overriding the set of cipher suites saves small amounts of ROM and
 | 
			
		||||
   RAM, and is a good practice in general if you know what server(s)
 | 
			
		||||
   you want to connect to.
 | 
			
		||||
 | 
			
		||||
  However it's extra important here because the howsmyssl API sends
 | 
			
		||||
  back the list of ciphers we send it as a JSON list in the, and we
 | 
			
		||||
  only have a 4096kB receive buffer. If the server supported maximum
 | 
			
		||||
  fragment length option then we wouldn't have this problem either,
 | 
			
		||||
  but we do so this is a good workaround.
 | 
			
		||||
 | 
			
		||||
  The ciphers chosen below are common ECDHE ciphers, the same ones
 | 
			
		||||
  Firefox uses when connecting to a TLSv1.2 server.
 | 
			
		||||
*/
 | 
			
		||||
#ifndef MBEDTLS_CONFIG_H
 | 
			
		||||
 | 
			
		||||
/* include_next picks up default config from extras/mbedtls/include/mbedtls/config.h */
 | 
			
		||||
#include_next<mbedtls/config.h>
 | 
			
		||||
 | 
			
		||||
#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
 | 
			
		||||
 | 
			
		||||
/* uncomment next line to include debug output from example */
 | 
			
		||||
//#define MBEDTLS_DEBUG_C
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										56
									
								
								extras/mbedtls/component.mk
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								extras/mbedtls/component.mk
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,56 @@
 | 
			
		|||
# Component makefile for mbedtls
 | 
			
		||||
 | 
			
		||||
# mbedtls by default builds into 3 libraries not one. We just use one for now (doesn't make a huge difference when static linking)
 | 
			
		||||
 | 
			
		||||
# Config:
 | 
			
		||||
# We supply our own hand tweaked mbedtls/config.h in our 'include' dir, the rest of upstream mbedtls is not changed.
 | 
			
		||||
 | 
			
		||||
MBEDTLS_DIR = $(mbedtls_ROOT)mbedtls/
 | 
			
		||||
INC_DIRS += $(mbedtls_ROOT)include $(MBEDTLS_DIR)include
 | 
			
		||||
 | 
			
		||||
# these OBJS_xxx variables  are copied directly from mbedtls/mbedtls/Makefile,
 | 
			
		||||
# minus a few values (noted in comments)
 | 
			
		||||
#
 | 
			
		||||
# If updating to a future mbedtls version you can just copy these in.
 | 
			
		||||
OBJS_CRYPTO=	aes.o		aesni.o		arc4.o		\
 | 
			
		||||
		asn1parse.o	asn1write.o	base64.o	\
 | 
			
		||||
		bignum.o	blowfish.o	camellia.o	\
 | 
			
		||||
		ccm.o		cipher.o	cipher_wrap.o	\
 | 
			
		||||
		ctr_drbg.o	des.o		dhm.o		\
 | 
			
		||||
		ecdh.o		ecdsa.o		ecp.o		\
 | 
			
		||||
		ecp_curves.o	entropy.o	entropy_poll.o	\
 | 
			
		||||
		error.o		gcm.o		havege.o	\
 | 
			
		||||
		hmac_drbg.o	md.o		md2.o		\
 | 
			
		||||
		md4.o		md5.o		md_wrap.o	\
 | 
			
		||||
		memory_buffer_alloc.o		oid.o		\
 | 
			
		||||
		padlock.o	pem.o		pk.o		\
 | 
			
		||||
		pk_wrap.o	pkcs12.o	pkcs5.o		\
 | 
			
		||||
		pkparse.o	pkwrite.o	platform.o	\
 | 
			
		||||
		ripemd160.o	rsa.o		sha1.o		\
 | 
			
		||||
		sha256.o	sha512.o	threading.o	\
 | 
			
		||||
		timing.o	version.o			\
 | 
			
		||||
		version_features.o		xtea.o
 | 
			
		||||
# minus net.o
 | 
			
		||||
 | 
			
		||||
OBJS_X509=	certs.o		pkcs11.o	x509.o		\
 | 
			
		||||
		x509_create.o	x509_crl.o	x509_crt.o	\
 | 
			
		||||
		x509_csr.o	x509write_crt.o	x509write_csr.o
 | 
			
		||||
 | 
			
		||||
OBJS_TLS=	debug.o				ssl_cache.o	\
 | 
			
		||||
		ssl_ciphersuites.o		ssl_cli.o	\
 | 
			
		||||
		ssl_cookie.o	ssl_srv.o	ssl_ticket.o	\
 | 
			
		||||
		ssl_tls.o
 | 
			
		||||
 | 
			
		||||
# args for passing into compile rule generation
 | 
			
		||||
mbedtls_INC_DIR =
 | 
			
		||||
mbedtls_SRC_DIR = $(mbedtls_ROOT)
 | 
			
		||||
mbedtls_EXTRA_SRC_FILES = $(patsubst %.o,$(MBEDTLS_DIR)library/%.c,$(OBJS_CRYPTO) $(OBJS_X509) $(OBJS_TLS))
 | 
			
		||||
 | 
			
		||||
# depending on cipher configuration, some mbedTLS variables are unused
 | 
			
		||||
mbedtls_CFLAGS = -Wno-error=unused-but-set-variable -Wno-error=unused-variable $(CFLAGS) 
 | 
			
		||||
 | 
			
		||||
$(eval $(call component_compile_rules,mbedtls))
 | 
			
		||||
 | 
			
		||||
# Helpful error if git submodule not initialised
 | 
			
		||||
$(MBEDTLS_DIR):
 | 
			
		||||
	$(error "mbedtls git submodule not installed. Please run 'git submodule update --init'")
 | 
			
		||||
							
								
								
									
										2444
									
								
								extras/mbedtls/include/mbedtls/config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2444
									
								
								extras/mbedtls/include/mbedtls/config.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										1
									
								
								extras/mbedtls/mbedtls
									
										
									
									
									
										Submodule
									
								
							
							
						
						
									
										1
									
								
								extras/mbedtls/mbedtls
									
										
									
									
									
										Submodule
									
								
							| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Subproject commit 0a0c22e0efcf2f8f71d7e16712f80b8f77326f72
 | 
			
		||||
							
								
								
									
										510
									
								
								extras/mbedtls/net_lwip.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										510
									
								
								extras/mbedtls/net_lwip.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,510 @@
 | 
			
		|||
/*
 | 
			
		||||
 *  TCP/IP or UDP/IP networking functions
 | 
			
		||||
 *  modified for LWIP support on ESP8266
 | 
			
		||||
 *
 | 
			
		||||
 *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
 | 
			
		||||
 *  Additions Copyright (C) 2015 Angus Gratton
 | 
			
		||||
 *  SPDX-License-Identifier: Apache-2.0
 | 
			
		||||
 *
 | 
			
		||||
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
			
		||||
 *  not use this file except in compliance with the License.
 | 
			
		||||
 *  You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *  http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 *  Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 *  See the License for the specific language governing permissions and
 | 
			
		||||
 *  limitations under the License.
 | 
			
		||||
 *
 | 
			
		||||
 *  This file is part of mbed TLS (https://tls.mbed.org)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#if !defined(MBEDTLS_CONFIG_FILE)
 | 
			
		||||
#include "mbedtls/config.h"
 | 
			
		||||
#else
 | 
			
		||||
#include MBEDTLS_CONFIG_FILE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(MBEDTLS_NET_C)
 | 
			
		||||
 | 
			
		||||
#include "mbedtls/net.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/socket.h>
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Prepare for using the sockets interface
 | 
			
		||||
 */
 | 
			
		||||
static int net_prepare( void )
 | 
			
		||||
{
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
    WSADATA wsaData;
 | 
			
		||||
 | 
			
		||||
    if( wsa_init_done == 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
 | 
			
		||||
 | 
			
		||||
        wsa_init_done = 1;
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
#endif
 | 
			
		||||
    return( 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Initialize a context
 | 
			
		||||
 */
 | 
			
		||||
void mbedtls_net_init( mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
    ctx->fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Initiate a TCP connection with host:port and the given protocol
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    struct addrinfo hints, *addr_list, *cur;
 | 
			
		||||
 | 
			
		||||
    if( ( ret = net_prepare() ) != 0 )
 | 
			
		||||
        return( ret );
 | 
			
		||||
 | 
			
		||||
    /* Do name resolution with both IPv6 and IPv4 */
 | 
			
		||||
    memset( &hints, 0, sizeof( hints ) );
 | 
			
		||||
    hints.ai_family = AF_UNSPEC;
 | 
			
		||||
    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
 | 
			
		||||
    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
 | 
			
		||||
 | 
			
		||||
    if( getaddrinfo( host, port, &hints, &addr_list ) != 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
 | 
			
		||||
 | 
			
		||||
    /* Try the sockaddrs until a connection succeeds */
 | 
			
		||||
    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
 | 
			
		||||
    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
 | 
			
		||||
    {
 | 
			
		||||
        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
 | 
			
		||||
                            cur->ai_protocol );
 | 
			
		||||
        if( ctx->fd < 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( connect( ctx->fd, cur->ai_addr, cur->ai_addrlen ) == 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ret = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        close( ctx->fd );
 | 
			
		||||
        ret = MBEDTLS_ERR_NET_CONNECT_FAILED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    freeaddrinfo( addr_list );
 | 
			
		||||
 | 
			
		||||
    return( ret );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Create a listening socket on bind_ip:port
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
 | 
			
		||||
{
 | 
			
		||||
    int n, ret;
 | 
			
		||||
    struct addrinfo hints, *addr_list, *cur;
 | 
			
		||||
 | 
			
		||||
    if( ( ret = net_prepare() ) != 0 )
 | 
			
		||||
        return( ret );
 | 
			
		||||
 | 
			
		||||
    /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
 | 
			
		||||
    memset( &hints, 0, sizeof( hints ) );
 | 
			
		||||
    hints.ai_family = AF_UNSPEC;
 | 
			
		||||
    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
 | 
			
		||||
    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
 | 
			
		||||
 | 
			
		||||
    if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
 | 
			
		||||
 | 
			
		||||
    /* Try the sockaddrs until a binding succeeds */
 | 
			
		||||
    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
 | 
			
		||||
    for( cur = addr_list; cur != NULL; cur = cur->ai_next )
 | 
			
		||||
    {
 | 
			
		||||
        ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype,
 | 
			
		||||
                            cur->ai_protocol );
 | 
			
		||||
        if( ctx->fd < 0 )
 | 
			
		||||
        {
 | 
			
		||||
            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        n = 1;
 | 
			
		||||
        if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR,
 | 
			
		||||
                        (const char *) &n, sizeof( n ) ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            close( ctx->fd );
 | 
			
		||||
            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( bind( ctx->fd, cur->ai_addr, cur->ai_addrlen ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            close( ctx->fd );
 | 
			
		||||
            ret = MBEDTLS_ERR_NET_BIND_FAILED;
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Listen only makes sense for TCP */
 | 
			
		||||
        if( proto == MBEDTLS_NET_PROTO_TCP )
 | 
			
		||||
        {
 | 
			
		||||
            if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 )
 | 
			
		||||
            {
 | 
			
		||||
                close( ctx->fd );
 | 
			
		||||
                ret = MBEDTLS_ERR_NET_LISTEN_FAILED;
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* I we ever get there, it's a success */
 | 
			
		||||
        ret = 0;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    freeaddrinfo( addr_list );
 | 
			
		||||
 | 
			
		||||
    return( ret );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
/*
 | 
			
		||||
 * Check if the requested operation would be blocking on a non-blocking socket
 | 
			
		||||
 * and thus 'failed' with a negative return value.
 | 
			
		||||
 */
 | 
			
		||||
static int net_would_block( const mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
    ((void) ctx);
 | 
			
		||||
    return( WSAGetLastError() == WSAEWOULDBLOCK );
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
/*
 | 
			
		||||
 * Check if the requested operation would be blocking on a non-blocking socket
 | 
			
		||||
 * and thus 'failed' with a negative return value.
 | 
			
		||||
 *
 | 
			
		||||
 * Note: on a blocking socket this function always returns 0!
 | 
			
		||||
 */
 | 
			
		||||
static int net_would_block( const mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
    /*
 | 
			
		||||
     * Never return 'WOULD BLOCK' on a non-blocking socket
 | 
			
		||||
     */
 | 
			
		||||
    if( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK )
 | 
			
		||||
        return( 0 );
 | 
			
		||||
 | 
			
		||||
    switch( errno )
 | 
			
		||||
    {
 | 
			
		||||
#if defined EAGAIN
 | 
			
		||||
        case EAGAIN:
 | 
			
		||||
#endif
 | 
			
		||||
#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN
 | 
			
		||||
        case EWOULDBLOCK:
 | 
			
		||||
#endif
 | 
			
		||||
            return( 1 );
 | 
			
		||||
    }
 | 
			
		||||
    return( 0 );
 | 
			
		||||
}
 | 
			
		||||
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Accept a connection from a remote client
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
 | 
			
		||||
                        mbedtls_net_context *client_ctx,
 | 
			
		||||
                        void *client_ip, size_t buf_size, size_t *ip_len )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    int type;
 | 
			
		||||
 | 
			
		||||
    struct sockaddr_in client_addr;
 | 
			
		||||
 | 
			
		||||
    socklen_t n = (socklen_t) sizeof( client_addr );
 | 
			
		||||
    socklen_t type_len = (socklen_t) sizeof( type );
 | 
			
		||||
 | 
			
		||||
    /* Is this a TCP or UDP socket? */
 | 
			
		||||
    if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
 | 
			
		||||
                    (void *) &type, (socklen_t *) &type_len ) != 0 ||
 | 
			
		||||
        ( type != SOCK_STREAM && type != SOCK_DGRAM ) )
 | 
			
		||||
    {
 | 
			
		||||
        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( type == SOCK_STREAM )
 | 
			
		||||
    {
 | 
			
		||||
        /* TCP: actual accept() */
 | 
			
		||||
        ret = client_ctx->fd = (int) accept( bind_ctx->fd,
 | 
			
		||||
                                             (struct sockaddr *) &client_addr, &n );
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        /* UDP: wait for a message, but keep it in the queue */
 | 
			
		||||
        char buf[1] = { 0 };
 | 
			
		||||
 | 
			
		||||
        ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
 | 
			
		||||
                        (struct sockaddr *) &client_addr, &n );
 | 
			
		||||
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
        if( ret == SOCKET_ERROR &&
 | 
			
		||||
            WSAGetLastError() == WSAEMSGSIZE )
 | 
			
		||||
        {
 | 
			
		||||
            /* We know buf is too small, thanks, just peeking here */
 | 
			
		||||
            ret = 0;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( ret < 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( net_would_block( bind_ctx ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
 | 
			
		||||
        return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* UDP: hijack the listening socket to communicate with the client,
 | 
			
		||||
     * then bind a new socket to accept new connections */
 | 
			
		||||
    if( type != SOCK_STREAM )
 | 
			
		||||
    {
 | 
			
		||||
        struct sockaddr_in local_addr;
 | 
			
		||||
        int one = 1;
 | 
			
		||||
 | 
			
		||||
        if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
 | 
			
		||||
 | 
			
		||||
        client_ctx->fd = bind_ctx->fd;
 | 
			
		||||
        bind_ctx->fd   = -1; /* In case we exit early */
 | 
			
		||||
 | 
			
		||||
        n = sizeof( struct sockaddr_in );
 | 
			
		||||
        if( getsockname( client_ctx->fd,
 | 
			
		||||
                         (struct sockaddr *) &local_addr, &n ) != 0 ||
 | 
			
		||||
            ( bind_ctx->fd = (int) socket( AF_INET,
 | 
			
		||||
                                           SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
 | 
			
		||||
            setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
 | 
			
		||||
                        (const char *) &one, sizeof( one ) ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return( MBEDTLS_ERR_NET_SOCKET_FAILED );
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 )
 | 
			
		||||
        {
 | 
			
		||||
            return( MBEDTLS_ERR_NET_BIND_FAILED );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if( client_ip != NULL )
 | 
			
		||||
    {
 | 
			
		||||
            struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
 | 
			
		||||
            *ip_len = sizeof( addr4->sin_addr.s_addr );
 | 
			
		||||
 | 
			
		||||
            if( buf_size < *ip_len )
 | 
			
		||||
                return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
 | 
			
		||||
 | 
			
		||||
            memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return( 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Set the socket blocking or non-blocking
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_set_block( mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
    u_long n = 0;
 | 
			
		||||
    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
 | 
			
		||||
#else
 | 
			
		||||
    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) & ~O_NONBLOCK ) );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int mbedtls_net_set_nonblock( mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
    u_long n = 1;
 | 
			
		||||
    return( ioctlsocket( ctx->fd, FIONBIO, &n ) );
 | 
			
		||||
#else
 | 
			
		||||
    return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL, 0 ) | O_NONBLOCK ) );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Portable usleep helper
 | 
			
		||||
 */
 | 
			
		||||
void mbedtls_net_usleep( unsigned long usec )
 | 
			
		||||
{
 | 
			
		||||
#if defined(_WIN32)
 | 
			
		||||
    Sleep( ( usec + 999 ) / 1000 );
 | 
			
		||||
#else
 | 
			
		||||
    struct timeval tv;
 | 
			
		||||
    tv.tv_sec  = usec / 1000000;
 | 
			
		||||
#if defined(__unix__) || defined(__unix) || \
 | 
			
		||||
    ( defined(__APPLE__) && defined(__MACH__) )
 | 
			
		||||
    tv.tv_usec = (suseconds_t) usec % 1000000;
 | 
			
		||||
#else
 | 
			
		||||
    tv.tv_usec = usec % 1000000;
 | 
			
		||||
#endif
 | 
			
		||||
    select( 0, NULL, NULL, NULL, &tv );
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Read at most 'len' characters
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    int fd = ((mbedtls_net_context *) ctx)->fd;
 | 
			
		||||
 | 
			
		||||
    if( fd < 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
			
		||||
 | 
			
		||||
    ret = (int) read( fd, buf, len );
 | 
			
		||||
 | 
			
		||||
    if( ret < 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( net_would_block( ctx ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
        if( WSAGetLastError() == WSAECONNRESET )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_CONN_RESET );
 | 
			
		||||
#else
 | 
			
		||||
        if( errno == EPIPE || errno == ECONNRESET )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_CONN_RESET );
 | 
			
		||||
 | 
			
		||||
        if( errno == EINTR )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        return( MBEDTLS_ERR_NET_RECV_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return( ret );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Read at most 'len' characters, blocking for at most 'timeout' ms
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
 | 
			
		||||
                      uint32_t timeout )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    struct timeval tv;
 | 
			
		||||
    fd_set read_fds;
 | 
			
		||||
    int fd = ((mbedtls_net_context *) ctx)->fd;
 | 
			
		||||
 | 
			
		||||
    if( fd < 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
			
		||||
 | 
			
		||||
    FD_ZERO( &read_fds );
 | 
			
		||||
    FD_SET( fd, &read_fds );
 | 
			
		||||
 | 
			
		||||
    tv.tv_sec  = timeout / 1000;
 | 
			
		||||
    tv.tv_usec = ( timeout % 1000 ) * 1000;
 | 
			
		||||
 | 
			
		||||
    ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv );
 | 
			
		||||
 | 
			
		||||
    /* Zero fds ready means we timed out */
 | 
			
		||||
    if( ret == 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_SSL_TIMEOUT );
 | 
			
		||||
 | 
			
		||||
    if( ret < 0 )
 | 
			
		||||
    {
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
        if( WSAGetLastError() == WSAEINTR )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
#else
 | 
			
		||||
        if( errno == EINTR )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_READ );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        return( MBEDTLS_ERR_NET_RECV_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* This call will not block */
 | 
			
		||||
    return( mbedtls_net_recv( ctx, buf, len ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Write at most 'len' characters
 | 
			
		||||
 */
 | 
			
		||||
int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
 | 
			
		||||
{
 | 
			
		||||
    int ret;
 | 
			
		||||
    int fd = ((mbedtls_net_context *) ctx)->fd;
 | 
			
		||||
 | 
			
		||||
    if( fd < 0 )
 | 
			
		||||
        return( MBEDTLS_ERR_NET_INVALID_CONTEXT );
 | 
			
		||||
 | 
			
		||||
    ret = (int) write( fd, buf, len );
 | 
			
		||||
 | 
			
		||||
    if( ret < 0 )
 | 
			
		||||
    {
 | 
			
		||||
        if( net_would_block( ctx ) != 0 )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_WRITE );
 | 
			
		||||
 | 
			
		||||
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
 | 
			
		||||
    !defined(EFI32)
 | 
			
		||||
        if( WSAGetLastError() == WSAECONNRESET )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_CONN_RESET );
 | 
			
		||||
#else
 | 
			
		||||
        if( errno == EPIPE || errno == ECONNRESET )
 | 
			
		||||
            return( MBEDTLS_ERR_NET_CONN_RESET );
 | 
			
		||||
 | 
			
		||||
        if( errno == EINTR )
 | 
			
		||||
            return( MBEDTLS_ERR_SSL_WANT_WRITE );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        return( MBEDTLS_ERR_NET_SEND_FAILED );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return( ret );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Gracefully close the connection
 | 
			
		||||
 */
 | 
			
		||||
void mbedtls_net_free( mbedtls_net_context *ctx )
 | 
			
		||||
{
 | 
			
		||||
    if( ctx->fd == -1 )
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    shutdown( ctx->fd, 2 );
 | 
			
		||||
    close( ctx->fd );
 | 
			
		||||
 | 
			
		||||
    ctx->fd = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* MBEDTLS_NET_C */
 | 
			
		||||
| 
						 | 
				
			
			@ -136,6 +136,68 @@ SECTIONS
 | 
			
		|||
    _dport0_data_end = ABSOLUTE(.);
 | 
			
		||||
  } >dport0_0_seg :dport0_0_phdr
 | 
			
		||||
 | 
			
		||||
  .text : ALIGN(4) /* IRAM */
 | 
			
		||||
  {
 | 
			
		||||
    _stext = .;
 | 
			
		||||
    _text_start = ABSOLUTE(.);
 | 
			
		||||
    . = ALIGN (16);
 | 
			
		||||
    *(.vecbase.text)
 | 
			
		||||
    *(.entry.text)
 | 
			
		||||
    *(.init.literal)
 | 
			
		||||
    *(.init)
 | 
			
		||||
    /* esp-open-rtos compiled source files use the .iram1.* section names for IRAM
 | 
			
		||||
       functions, etc. */
 | 
			
		||||
    *(.iram1.*)
 | 
			
		||||
    /* SDK libraries expect their .text sections to link to iram, not irom */
 | 
			
		||||
    *sdklib*:*(.literal .text .literal.* .text.*)
 | 
			
		||||
    /* libgcc integer functions also need to be in .text, as some are called before
 | 
			
		||||
       flash is mapped (also performance)
 | 
			
		||||
    */
 | 
			
		||||
    *libgcc.a:*i3.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    /* libc also in IRAM */
 | 
			
		||||
    *libc.a:*malloc.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*mallocr.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*freer.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memcpy.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memset.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memcmp.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memmove.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*rand.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*bzero.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*lock.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    *libc.a:*printf.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*findfp.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*fputwc.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    /* xthal_set_intset() called from PendSV in NMI context */
 | 
			
		||||
    *libhal.a:*set_intset.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
 | 
			
		||||
    *(.fini.literal)
 | 
			
		||||
    *(.fini)
 | 
			
		||||
    *(.gnu.version)
 | 
			
		||||
    _text_end = ABSOLUTE(.);
 | 
			
		||||
    _etext = .;
 | 
			
		||||
  } >iram1_0_seg :iram1_0_phdr
 | 
			
		||||
 | 
			
		||||
  .irom0.text : ALIGN(4)
 | 
			
		||||
  {
 | 
			
		||||
    _irom0_text_start = ABSOLUTE(.);
 | 
			
		||||
    /* esp-open-rtos compiled code goes into IROM by default
 | 
			
		||||
       (except for libgcc which is matched above.)
 | 
			
		||||
    */
 | 
			
		||||
    *(.literal .text .literal.* .text.*)
 | 
			
		||||
    /* mbedtls rodata */
 | 
			
		||||
    *mbedtls.a:*.o(.rodata.* .rodata)
 | 
			
		||||
    /* actual certificate in example (TEMPORARY HACK) */
 | 
			
		||||
    *:cert.o(.rodata.* .rodata)
 | 
			
		||||
    /* Anything explicitly marked as "irom" or "irom0" should go here */
 | 
			
		||||
    *(.irom.* .irom.*.* .irom0.*)
 | 
			
		||||
    _irom0_text_end = ABSOLUTE(.);
 | 
			
		||||
  } >irom0_0_seg :irom0_0_phdr
 | 
			
		||||
 | 
			
		||||
  .data : ALIGN(4)
 | 
			
		||||
  {
 | 
			
		||||
    _data_start = ABSOLUTE(.);
 | 
			
		||||
| 
						 | 
				
			
			@ -218,63 +280,6 @@ SECTIONS
 | 
			
		|||
  } >dram0_0_seg :dram0_0_bss_phdr
 | 
			
		||||
/* __stack = 0x3ffc8000; */
 | 
			
		||||
 | 
			
		||||
  .text : ALIGN(4) /* IRAM */
 | 
			
		||||
  {
 | 
			
		||||
    _stext = .;
 | 
			
		||||
    _text_start = ABSOLUTE(.);
 | 
			
		||||
    . = ALIGN (16);
 | 
			
		||||
    *(.vecbase.text)
 | 
			
		||||
    *(.entry.text)
 | 
			
		||||
    *(.init.literal)
 | 
			
		||||
    *(.init)
 | 
			
		||||
    /* esp-open-rtos compiled source files use the .iram1.* section names for IRAM
 | 
			
		||||
       functions, etc. */
 | 
			
		||||
    *(.iram1.*)
 | 
			
		||||
    /* SDK libraries expect their .text sections to link to iram, not irom */
 | 
			
		||||
    *sdklib*:*(.literal .text .literal.* .text.*)
 | 
			
		||||
    /* libgcc integer functions also need to be in .text, as some are called before
 | 
			
		||||
       flash is mapped (also performance)
 | 
			
		||||
    */
 | 
			
		||||
    *libgcc.a:*i3.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    /* libc also in IRAM */
 | 
			
		||||
    *libc.a:*malloc.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*mallocr.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*freer.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memcpy.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memset.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memcmp.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*memmove.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*rand.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*bzero.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*lock.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    *libc.a:*printf.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*findfp.o(.literal .text .literal.* .text.*)
 | 
			
		||||
    *libc.a:*fputwc.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    /* xthal_set_intset() called from PendSV in NMI context */
 | 
			
		||||
    *libhal.a:*set_intset.o(.literal .text .literal.* .text.*)
 | 
			
		||||
 | 
			
		||||
    *(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
 | 
			
		||||
    *(.fini.literal)
 | 
			
		||||
    *(.fini)
 | 
			
		||||
    *(.gnu.version)
 | 
			
		||||
    _text_end = ABSOLUTE(.);
 | 
			
		||||
    _etext = .;
 | 
			
		||||
  } >iram1_0_seg :iram1_0_phdr
 | 
			
		||||
 | 
			
		||||
  .irom0.text : ALIGN(4)
 | 
			
		||||
  {
 | 
			
		||||
    _irom0_text_start = ABSOLUTE(.);
 | 
			
		||||
    /* esp-open-rtos compiled code goes into IROM by default
 | 
			
		||||
       (except for libgcc which is matched above.)
 | 
			
		||||
    */
 | 
			
		||||
    *(.literal .text .literal.* .text.*)
 | 
			
		||||
    /* Anything explicitly marked as "irom" or "irom0" should go here */
 | 
			
		||||
    *(.irom.* .irom.*.* .irom0.*)
 | 
			
		||||
    _irom0_text_end = ABSOLUTE(.);
 | 
			
		||||
  } >irom0_0_seg :irom0_0_phdr
 | 
			
		||||
 | 
			
		||||
  .lit4 : ALIGN(4)
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
# Component makefile for LWIP
 | 
			
		||||
 | 
			
		||||
LWIP_DIR = $(lwip_ROOT)lwip/src/
 | 
			
		||||
INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip
 | 
			
		||||
INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(lwip_ROOT)include $(LWIP_DIR)include/posix $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip
 | 
			
		||||
 | 
			
		||||
# args for passing into compile rule generation
 | 
			
		||||
lwip_INC_DIR =  # all in INC_DIRS, needed for normal operation
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue