From 3fcec6106ff5ca0405bdae8b15166de43a021107 Mon Sep 17 00:00:00 2001 From: Angus Gratton <gus@projectgus.com> Date: Tue, 2 Jun 2015 10:43:08 +1000 Subject: [PATCH] Swap binary axTLS libssl for direct compiled version --- FreeRTOS/Source/portable/esp8266/portmacro.h | 1 + FreeRTOS/Source/portable/esp8266/sdk_compat.c | 2 +- axtls/axtls_esp_stubs.c | 29 + axtls/component.mk | 19 + .../ssl_config.h => axtls/include/config.h | 77 +- axtls/include/os_int.h | 6 + .../ssl_os_port.h => axtls/include/os_port.h | 53 +- common.mk | 2 +- include/esp8266.h | 2 +- include/ssl/ssl_bigint.h | 99 -- include/ssl/ssl_bigint_impl.h | 131 --- include/ssl/ssl_crypto.h | 230 ----- include/ssl/ssl_crypto_misc.h | 172 ---- include/ssl/ssl_ssl.h | 500 ---------- include/ssl/ssl_tls1.h | 298 ------ include/ssl/ssl_version.h | 1 - lib/libssl.a | Bin 137692 -> 0 bytes lib/symbols_norename.txt | 2 + lwip/component.mk | 2 +- lwip/include/arch/cc.h | 10 +- lwip/include/lwipopts.h | 879 +++++++++--------- 21 files changed, 590 insertions(+), 1925 deletions(-) create mode 100644 axtls/axtls_esp_stubs.c create mode 100644 axtls/component.mk rename include/ssl/ssl_config.h => axtls/include/config.h (66%) create mode 100644 axtls/include/os_int.h rename include/ssl/ssl_os_port.h => axtls/include/os_port.h (60%) delete mode 100644 include/ssl/ssl_bigint.h delete mode 100644 include/ssl/ssl_bigint_impl.h delete mode 100644 include/ssl/ssl_crypto.h delete mode 100644 include/ssl/ssl_crypto_misc.h delete mode 100644 include/ssl/ssl_ssl.h delete mode 100644 include/ssl/ssl_tls1.h delete mode 100644 include/ssl/ssl_version.h delete mode 100644 lib/libssl.a diff --git a/FreeRTOS/Source/portable/esp8266/portmacro.h b/FreeRTOS/Source/portable/esp8266/portmacro.h index a41b1f7..3c54612 100644 --- a/FreeRTOS/Source/portable/esp8266/portmacro.h +++ b/FreeRTOS/Source/portable/esp8266/portmacro.h @@ -70,6 +70,7 @@ extern "C" { #endif +#include "esp8266.h" #include "espressif/esp8266/ets_sys.h" #include <stdint.h> #include <xtruntime.h> diff --git a/FreeRTOS/Source/portable/esp8266/sdk_compat.c b/FreeRTOS/Source/portable/esp8266/sdk_compat.c index 9691138..9ca5cd4 100644 --- a/FreeRTOS/Source/portable/esp8266/sdk_compat.c +++ b/FreeRTOS/Source/portable/esp8266/sdk_compat.c @@ -4,7 +4,7 @@ #include <string.h> #include "FreeRTOS.h" -/* SDK uses this and so does lwip, it was defined in libudhcp.a +/* SDK uses errno. errno was defined in libudhcp.a but that library has been removed. */ int errno; diff --git a/axtls/axtls_esp_stubs.c b/axtls/axtls_esp_stubs.c new file mode 100644 index 0000000..00b7fd6 --- /dev/null +++ b/axtls/axtls_esp_stubs.c @@ -0,0 +1,29 @@ +#include <time.h> +#include <sys/time.h> +#include <stdio.h> +/* + * Stub time functions for TLS time-related operations + * + * ESPTODO: Revisit these soon as gettimeofday() is used for entropy + */ + +time_t time(time_t *t) +{ + return 0; +} + +time_t mktime(struct tm *tm) +{ + return 0; +} + +int gettimeofday(struct timeval *tv, void *tz) +{ + return 0; +} + +void abort(void) +{ + printf("abort() was called.\r\n"); + while(1) {} +} diff --git a/axtls/component.mk b/axtls/component.mk new file mode 100644 index 0000000..185f47e --- /dev/null +++ b/axtls/component.mk @@ -0,0 +1,19 @@ +# Component makefile for axTLS + +# axTLS has its own configure and build system, but it's not particularly +# designed for embedded systems. For now we're just imposing the ESP Open RTOS +# build system over the top. + +# We supply our own hand tweaked config.h in the external 'include' dir. + +AXTLS_DIR = $(ROOT)axtls/axtls/ +INC_DIRS += $(ROOT)axtls/include $(AXTLS_DIR)ssl $(AXTLS_DIR)crypto + +# args for passing into compile rule generation +axtls_ROOT = $(ROOT)axtls +axtls_INC_DIR = $(AXTLS_DIR)include $(AXTLS_DIR) +axtls_SRC_DIR = $(AXTLS_DIR)crypto $(AXTLS_DIR)ssl $(ROOT)axtls + +#axtls_CFLAGS = $(CFLAGS) -Wno-address + +$(eval $(call component_compile_rules,axtls)) diff --git a/include/ssl/ssl_config.h b/axtls/include/config.h similarity index 66% rename from include/ssl/ssl_config.h rename to axtls/include/config.h index 3404b5b..175d083 100644 --- a/include/ssl/ssl_config.h +++ b/axtls/include/config.h @@ -1,18 +1,18 @@ /* * Automatically generated header file: don't edit */ - -#define HAVE_DOT_CONFIG 1 +#define HAVE_DOT_CONFIG 0 #undef CONFIG_PLATFORM_LINUX -#define CONFIG_PLATFORM_CYGWIN 1 +#undef CONFIG_PLATFORM_CYGWIN #undef CONFIG_PLATFORM_WIN32 /* * General Configuration */ #define PREFIX "/usr/local" -#define CONFIG_DEBUG 1 -#undef CONFIG_STRIP_UNWANTED_SECTIONS +#define CROSS "xtensa-lx106-elf-" +#undef CONFIG_DEBUG +#define CONFIG_STRIP_UNWANTED_SECTIONS 1 #undef CONFIG_VISUAL_STUDIO_7_0 #undef CONFIG_VISUAL_STUDIO_8_0 #undef CONFIG_VISUAL_STUDIO_10_0 @@ -22,18 +22,26 @@ #define CONFIG_EXTRA_CFLAGS_OPTIONS "" #define CONFIG_EXTRA_LDFLAGS_OPTIONS "" +/* + * Embedded System Options (added for ESP RTOS SDK, don't have config entries yetr) + */ +#define CONFIG_NO_FILESYSTEM 1 +#define CONFIG_USE_RAND 1 +#define CONFIG_MAX_PLAIN_LENGTH 1024 +#define CONFIG_MAX_KEY_BYTE_SIZE 256 /* for max 2048 bit keys (untested with >1024 bit keys) */ + /* * SSL Library */ #undef CONFIG_SSL_SERVER_ONLY #undef CONFIG_SSL_CERT_VERIFICATION -#undef CONFIG_SSL_ENABLE_CLIENT -#define CONFIG_SSL_FULL_MODE 1 +#define CONFIG_SSL_ENABLE_CLIENT 1 +#undef CONFIG_SSL_FULL_MODE #undef CONFIG_SSL_SKELETON_MODE #undef CONFIG_SSL_PROT_LOW #define CONFIG_SSL_PROT_MEDIUM 1 #undef CONFIG_SSL_PROT_HIGH -#define CONFIG_SSL_USE_DEFAULT_KEY +#undef CONFIG_SSL_USE_DEFAULT_KEY #define CONFIG_SSL_PRIVATE_KEY_LOCATION "" #define CONFIG_SSL_PRIVATE_KEY_PASSWORD "" #define CONFIG_SSL_X509_CERT_LOCATION "" @@ -42,45 +50,37 @@ #define CONFIG_SSL_X509_ORGANIZATION_NAME "" #define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME "" #undef CONFIG_SSL_ENABLE_V23_HANDSHAKE -#define CONFIG_SSL_HAS_PEM 1 +#undef CONFIG_SSL_HAS_PEM #undef CONFIG_SSL_USE_PKCS12 #define CONFIG_SSL_EXPIRY_TIME 24 -#define CONFIG_X509_MAX_CA_CERTS 150 +#define CONFIG_X509_MAX_CA_CERTS 1 #define CONFIG_SSL_MAX_CERTS 3 #undef CONFIG_SSL_CTX_MUTEXING -//#define CONFIG_USE_DEV_URANDOM 1 +#undef CONFIG_USE_DEV_URANDOM #undef CONFIG_WIN32_USE_CRYPTO_LIB #undef CONFIG_OPENSSL_COMPATIBLE #undef CONFIG_PERFORMANCE_TESTING -#define CONFIG_SSL_TEST 1 +#undef CONFIG_SSL_TEST #undef CONFIG_AXTLSWRAP -#define CONFIG_AXHTTPD 1 - -/* - * Axhttpd Configuration - */ +#undef CONFIG_AXHTTPD #undef CONFIG_HTTP_STATIC_BUILD -#define CONFIG_HTTP_PORT 80 -#define CONFIG_HTTP_HTTPS_PORT 443 -#define CONFIG_HTTP_SESSION_CACHE_SIZE 5 -#define CONFIG_HTTP_WEBROOT "../www" -#define CONFIG_HTTP_TIMEOUT 300 - -/* - * CGI - */ -#undef CONFIG_HTTP_HAS_CGI -#define CONFIG_HTTP_CGI_EXTENSIONS ".lua,.lp,.php" -#define CONFIG_HTTP_ENABLE_LUA 1 -#define CONFIG_HTTP_LUA_PREFIX "/usr" +#define CONFIG_HTTP_PORT +#define CONFIG_HTTP_HTTPS_PORT +#define CONFIG_HTTP_SESSION_CACHE_SIZE +#define CONFIG_HTTP_WEBROOT "" +#define CONFIG_HTTP_TIMEOUT +#undef CONFIG_HTTP_HAS_CGI +#define CONFIG_HTTP_CGI_EXTENSIONS "" +#undef CONFIG_HTTP_ENABLE_LUA +#define CONFIG_HTTP_LUA_PREFIX "" #undef CONFIG_HTTP_BUILD_LUA -#define CONFIG_HTTP_CGI_LAUNCHER "/usr/bin/cgi" -#define CONFIG_HTTP_DIRECTORIES 1 -#define CONFIG_HTTP_HAS_AUTHORIZATION 1 +#define CONFIG_HTTP_CGI_LAUNCHER "" +#undef CONFIG_HTTP_DIRECTORIES +#undef CONFIG_HTTP_HAS_AUTHORIZATION #undef CONFIG_HTTP_HAS_IPV6 #undef CONFIG_HTTP_ENABLE_DIFFERENT_USER #define CONFIG_HTTP_USER "" -#define CONFIG_HTTP_VERBOSE 0 +#undef CONFIG_HTTP_VERBOSE #undef CONFIG_HTTP_IS_DAEMON /* @@ -101,8 +101,8 @@ /* * Samples */ -#define CONFIG_SAMPLES 1 -#define CONFIG_C_SAMPLES 1 +#undef CONFIG_SAMPLES +#undef CONFIG_C_SAMPLES #undef CONFIG_CSHARP_SAMPLES #undef CONFIG_VBNET_SAMPLES #undef CONFIG_JAVA_SAMPLES @@ -117,11 +117,12 @@ #define CONFIG_BIGINT_BARRETT 1 #define CONFIG_BIGINT_CRT 1 #undef CONFIG_BIGINT_KARATSUBA -#define MUL_KARATSUBA_THRESH -#define SQU_KARATSUBA_THRESH +#define MUL_KARATSUBA_THRESH +#define SQU_KARATSUBA_THRESH #define CONFIG_BIGINT_SLIDING_WINDOW 1 #define CONFIG_BIGINT_SQUARE 1 #define CONFIG_BIGINT_CHECK_ON 1 #define CONFIG_INTEGER_32BIT 1 #undef CONFIG_INTEGER_16BIT #undef CONFIG_INTEGER_8BIT + diff --git a/axtls/include/os_int.h b/axtls/include/os_int.h new file mode 100644 index 0000000..3fc09cd --- /dev/null +++ b/axtls/include/os_int.h @@ -0,0 +1,6 @@ +#ifndef _OS_INT_H +#define _OS_INT_H + +#include <stdint.h> + +#endif diff --git a/include/ssl/ssl_os_port.h b/axtls/include/os_port.h similarity index 60% rename from include/ssl/ssl_os_port.h rename to axtls/include/os_port.h index a68b9e1..67fc3db 100644 --- a/include/ssl/ssl_os_port.h +++ b/axtls/include/os_port.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2007, Cameron Rich + * Copyright (c) 2007-2015, Cameron Rich + * Modifications Copyright (c) 2015 Superhouse Automation Pty Ltd * * All rights reserved. * @@ -34,28 +35,58 @@ * Some stuff to minimise the differences between windows and linux/unix */ -#ifndef HEADER_OS_PORT_H -#define HEADER_OS_PORT_H +#ifndef _HEADER_OS_PORT_H +#define _HEADER_OS_PORT_H #ifdef __cplusplus extern "C" { #endif -#include "esp_common.h" - -#if 0 -#define ssl_printf(fmt, args...) os_printf(fmt,## args) -#else -#define ssl_printf(fmt, args...) +#include "FreeRTOS.h" +#include "os_int.h" +#include "config.h" +#include <stdio.h> +#include <pwd.h> +#include <netdb.h> +//#include <fcntl.h> +#include <errno.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <posix/sys/socket.h> +#include <sys/wait.h> +#include <ipv4/lwip/inet.h> +#if defined(CONFIG_SSL_CTX_MUTEXING) +#include "semphr.h" #endif -#define STDCALL -#define EXP_FUNC +#define SOCKET_READ(A,B,C) read(A,B,C) +#define SOCKET_WRITE(A,B,C) write(A,B,C) +#define SOCKET_CLOSE(A) if (A >= 0) close(A) +#define TTY_FLUSH() +static inline uint64_t be64toh(uint64_t x) { + return ntohl(x>>32) | ((uint64_t)(ntohl(x)) << 32); +} + +void exit_now(const char *format, ...) __attribute((noreturn)); + +#define EXP_FUNC +#define STDCALL + +/* Mutex definitions */ +#if defined(CONFIG_SSL_CTX_MUTEXING) +#define SSL_CTX_MUTEX_TYPE xSemaphoreHandle +#define SSL_CTX_MUTEX_INIT(A) vSemaphoreCreateBinaryCreateMutex(A) +#define SSL_CTX_MUTEX_DESTROY(A) vSemaphoreDelete(A) +#define SSL_CTX_LOCK(A) xSemaphoreTakeRecursive(A, portMAX_DELAY) +#define SSL_CTX_UNLOCK(A) xSemaphoreGiveRecursive(A) +#else +#define SSL_CTX_MUTEX_TYPE #define SSL_CTX_MUTEX_INIT(A) #define SSL_CTX_MUTEX_DESTROY(A) #define SSL_CTX_LOCK(A) #define SSL_CTX_UNLOCK(A) +#endif #ifdef __cplusplus } diff --git a/common.mk b/common.mk index fa8082f..c5467d0 100644 --- a/common.mk +++ b/common.mk @@ -53,7 +53,7 @@ OBJCOPY = $(CROSS)objcopy # Source components to compile and link. Each of these are subdirectories # of the root, with a 'component.mk' file. -COMPONENTS ?= FreeRTOS lwip +COMPONENTS ?= FreeRTOS lwip axtls # binary esp-iot-rtos SDK libraries to link. These are pre-processed prior to linking. SDK_LIBS ?= main net80211 phy pp wpa diff --git a/include/esp8266.h b/include/esp8266.h index a58a9be..492ed46 100644 --- a/include/esp8266.h +++ b/include/esp8266.h @@ -1,5 +1,6 @@ /* esp8266.h * +<<<<<<< HEAD * ESP-specific SoC-level addresses, macros, etc. * Part of esp-open-rtos * @@ -23,7 +24,6 @@ */ #define IROM __attribute__((section(".irom0"))) const - /* Register addresses ESPTODO: break this out to its own header file and clean it up, add other regs, etc. diff --git a/include/ssl/ssl_bigint.h b/include/ssl/ssl_bigint.h deleted file mode 100644 index 99f5415..0000000 --- a/include/ssl/ssl_bigint.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2007, Cameron Rich - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BIGINT_HEADER -#define BIGINT_HEADER - -#include "ssl/ssl_crypto.h" - -BI_CTX *bi_initialize(void); -void bi_terminate(BI_CTX *ctx); -void bi_permanent(bigint *bi); -void bi_depermanent(bigint *bi); -void bi_clear_cache(BI_CTX *ctx); -void bi_free(BI_CTX *ctx, bigint *bi); -bigint *bi_copy(bigint *bi); -bigint *bi_clone(BI_CTX *ctx, const bigint *bi); -void bi_export(BI_CTX *ctx, bigint *bi, uint8_t *data, int size); -bigint *bi_import(BI_CTX *ctx, const uint8_t *data, int len); -bigint *int_to_bi(BI_CTX *ctx, comp i); - -/* the functions that actually do something interesting */ -bigint *bi_add(BI_CTX *ctx, bigint *bia, bigint *bib); -bigint *bi_subtract(BI_CTX *ctx, bigint *bia, - bigint *bib, int *is_negative); -bigint *bi_divide(BI_CTX *ctx, bigint *bia, bigint *bim, int is_mod); -bigint *bi_multiply(BI_CTX *ctx, bigint *bia, bigint *bib); -bigint *bi_mod_power(BI_CTX *ctx, bigint *bi, bigint *biexp); -bigint *bi_mod_power2(BI_CTX *ctx, bigint *bi, bigint *bim, bigint *biexp); -int bi_compare(bigint *bia, bigint *bib); -void bi_set_mod(BI_CTX *ctx, bigint *bim, int mod_offset); -void bi_free_mod(BI_CTX *ctx, int mod_offset); - -#ifdef CONFIG_SSL_FULL_MODE -void bi_print(const char *label, bigint *bi); -bigint *bi_str_import(BI_CTX *ctx, const char *data); -#endif - -/** - * @def bi_mod - * Find the residue of B. bi_set_mod() must be called before hand. - */ -#define bi_mod(A, B) bi_divide(A, B, ctx->bi_mod[ctx->mod_offset], 1) - -/** - * bi_residue() is technically the same as bi_mod(), but it uses the - * appropriate reduction technique (which is bi_mod() when doing classical - * reduction). - */ -#if defined(CONFIG_BIGINT_MONTGOMERY) -#define bi_residue(A, B) bi_mont(A, B) -bigint *bi_mont(BI_CTX *ctx, bigint *bixy); -#elif defined(CONFIG_BIGINT_BARRETT) -#define bi_residue(A, B) bi_barrett(A, B) -bigint *bi_barrett(BI_CTX *ctx, bigint *bi); -#else /* if defined(CONFIG_BIGINT_CLASSICAL) */ -#define bi_residue(A, B) bi_mod(A, B) -#endif - -#ifdef CONFIG_BIGINT_SQUARE -bigint *bi_square(BI_CTX *ctx, bigint *bi); -#else -#define bi_square(A, B) bi_multiply(A, bi_copy(B), B) -#endif - -#ifdef CONFIG_BIGINT_CRT -bigint *bi_crt(BI_CTX *ctx, bigint *bi, - bigint *dP, bigint *dQ, - bigint *p, bigint *q, - bigint *qInv); -#endif - -#endif diff --git a/include/ssl/ssl_bigint_impl.h b/include/ssl/ssl_bigint_impl.h deleted file mode 100644 index c82fefb..0000000 --- a/include/ssl/ssl_bigint_impl.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2007, Cameron Rich - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BIGINT_IMPL_HEADER -#define BIGINT_IMPL_HEADER - -/* Maintain a number of precomputed variables when doing reduction */ -#define BIGINT_M_OFFSET 0 /**< Normal modulo offset. */ -#ifdef CONFIG_BIGINT_CRT -#define BIGINT_P_OFFSET 1 /**< p modulo offset. */ -#define BIGINT_Q_OFFSET 2 /**< q module offset. */ -#define BIGINT_NUM_MODS 3 /**< The number of modulus constants used. */ -#else -#define BIGINT_NUM_MODS 1 -#endif - -/* Architecture specific functions for big ints */ -#if defined(CONFIG_INTEGER_8BIT) -#define COMP_RADIX 256U /**< Max component + 1 */ -#define COMP_MAX 0xFFFFU/**< (Max dbl comp -1) */ -#define COMP_BIT_SIZE 8 /**< Number of bits in a component. */ -#define COMP_BYTE_SIZE 1 /**< Number of bytes in a component. */ -#define COMP_NUM_NIBBLES 2 /**< Used For diagnostics only. */ -typedef uint8_t comp; /**< A single precision component. */ -typedef uint16_t long_comp; /**< A double precision component. */ -typedef int16_t slong_comp; /**< A signed double precision component. */ -#elif defined(CONFIG_INTEGER_16BIT) -#define COMP_RADIX 65536U /**< Max component + 1 */ -#define COMP_MAX 0xFFFFFFFFU/**< (Max dbl comp -1) */ -#define COMP_BIT_SIZE 16 /**< Number of bits in a component. */ -#define COMP_BYTE_SIZE 2 /**< Number of bytes in a component. */ -#define COMP_NUM_NIBBLES 4 /**< Used For diagnostics only. */ -typedef uint16_t comp; /**< A single precision component. */ -typedef uint32_t long_comp; /**< A double precision component. */ -typedef int32_t slong_comp; /**< A signed double precision component. */ -#else /* regular 32 bit */ -#ifdef WIN32 -#define COMP_RADIX 4294967296i64 -#define COMP_MAX 0xFFFFFFFFFFFFFFFFui64 -#else -#define COMP_RADIX 4294967296ULL /**< Max component + 1 */ -#define COMP_MAX 0xFFFFFFFFFFFFFFFFULL/**< (Max dbl comp -1) */ -#endif -#define COMP_BIT_SIZE 32 /**< Number of bits in a component. */ -#define COMP_BYTE_SIZE 4 /**< Number of bytes in a component. */ -#define COMP_NUM_NIBBLES 8 /**< Used For diagnostics only. */ -typedef uint32_t comp; /**< A single precision component. */ -typedef uint64_t long_comp; /**< A double precision component. */ -typedef sint64_t slong_comp; /**< A signed double precision component. */ -#endif - -/** - * @struct _bigint - * @brief A big integer basic object - */ -struct _bigint -{ - struct _bigint* next; /**< The next bigint in the cache. */ - short size; /**< The number of components in this bigint. */ - short max_comps; /**< The heapsize allocated for this bigint */ - int refs; /**< An internal reference count. */ - comp* comps; /**< A ptr to the actual component data */ -}; - -typedef struct _bigint bigint; /**< An alias for _bigint */ - -/** - * Maintains the state of the cache, and a number of variables used in - * reduction. - */ -typedef struct /**< A big integer "session" context. */ -{ - bigint *active_list; /**< Bigints currently used. */ - bigint *free_list; /**< Bigints not used. */ - bigint *bi_radix; /**< The radix used. */ - bigint *bi_mod[BIGINT_NUM_MODS]; /**< modulus */ - -#if defined(CONFIG_BIGINT_MONTGOMERY) - bigint *bi_RR_mod_m[BIGINT_NUM_MODS]; /**< R^2 mod m */ - bigint *bi_R_mod_m[BIGINT_NUM_MODS]; /**< R mod m */ - comp N0_dash[BIGINT_NUM_MODS]; -#elif defined(CONFIG_BIGINT_BARRETT) - bigint *bi_mu[BIGINT_NUM_MODS]; /**< Storage for mu */ -#endif - bigint *bi_normalised_mod[BIGINT_NUM_MODS]; /**< Normalised mod storage. */ - bigint **g; /**< Used by sliding-window. */ - int window; /**< The size of the sliding window */ - int active_count; /**< Number of active bigints. */ - int free_count; /**< Number of free bigints. */ - -#ifdef CONFIG_BIGINT_MONTGOMERY - uint8_t use_classical; /**< Use classical reduction. */ -#endif - uint8_t mod_offset; /**< The mod offset we are using */ -} BI_CTX; - -#ifndef WIN32 -#define max(a,b) ((a)>(b)?(a):(b)) /**< Find the maximum of 2 numbers. */ -#define min(a,b) ((a)<(b)?(a):(b)) /**< Find the minimum of 2 numbers. */ -#endif - -#define PERMANENT 0x7FFF55AA /**< A magic number for permanents. */ - -#endif diff --git a/include/ssl/ssl_crypto.h b/include/ssl/ssl_crypto.h deleted file mode 100644 index 1ea461a..0000000 --- a/include/ssl/ssl_crypto.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2007, Cameron Rich - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file crypto.h - */ - -#ifndef HEADER_CRYPTO_H -#define HEADER_CRYPTO_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ssl/ssl_config.h" -#include "ssl/ssl_bigint_impl.h" -#include "ssl/ssl_bigint.h" - -#ifndef STDCALL -#define STDCALL -#endif -#ifndef EXP_FUNC -#define EXP_FUNC -#endif - - -/* enable features based on a 'super-set' capbaility. */ -#if defined(CONFIG_SSL_FULL_MODE) -#define CONFIG_SSL_ENABLE_CLIENT -#define CONFIG_SSL_CERT_VERIFICATION -#elif defined(CONFIG_SSL_ENABLE_CLIENT) -#define CONFIG_SSL_CERT_VERIFICATION -#endif - -/************************************************************************** - * AES declarations - **************************************************************************/ - -#define AES_MAXROUNDS 14 -#define AES_BLOCKSIZE 16 -#define AES_IV_SIZE 16 - -typedef struct aes_key_st -{ - uint16_t rounds; - uint16_t key_size; - uint32_t ks[(AES_MAXROUNDS+1)*8]; - uint8_t iv[AES_IV_SIZE]; -} AES_CTX; - -typedef enum -{ - AES_MODE_128, - AES_MODE_256 -} AES_MODE; - -void AES_set_key(AES_CTX *ctx, const uint8_t *key, - const uint8_t *iv, AES_MODE mode); -void AES_cbc_encrypt(AES_CTX *ctx, const uint8_t *msg, - uint8_t *out, int length); -void AES_cbc_decrypt(AES_CTX *ks, const uint8_t *in, uint8_t *out, int length); -void AES_convert_key(AES_CTX *ctx); - -/************************************************************************** - * RC4 declarations - **************************************************************************/ - -typedef struct -{ - uint8_t x, y, m[256]; -} RC4_CTX; - -void RC4_setup(RC4_CTX *s, const uint8_t *key, int length); -void RC4_crypt(RC4_CTX *s, const uint8_t *msg, uint8_t *data, int length); - -/************************************************************************** - * SHA1 declarations - **************************************************************************/ - -#define SHA1_SIZE 20 - -/* - * This structure will hold context information for the SHA-1 - * hashing operation - */ -typedef struct -{ - uint32_t Intermediate_Hash[SHA1_SIZE/4]; /* Message Digest */ - uint32_t Length_Low; /* Message length in bits */ - uint32_t Length_High; /* Message length in bits */ - uint16_t Message_Block_Index; /* Index into message block array */ - uint8_t Message_Block[64]; /* 512-bit message blocks */ -} SHA1_CTX; - -void SHA1_Init(SHA1_CTX *); -void SHA1_Update(SHA1_CTX *, const uint8_t * msg, int len); -void SHA1_Final(uint8_t *digest, SHA1_CTX *); - -/************************************************************************** - * MD2 declarations - **************************************************************************/ - -#define MD2_SIZE 16 - -typedef struct -{ - unsigned char cksum[16]; /* checksum of the data block */ - unsigned char state[48]; /* intermediate digest state */ - unsigned char buffer[16]; /* data block being processed */ - int left; /* amount of data in buffer */ -} MD2_CTX; - -EXP_FUNC void STDCALL MD2_Init(MD2_CTX *ctx); -EXP_FUNC void STDCALL MD2_Update(MD2_CTX *ctx, const uint8_t *input, int ilen); -EXP_FUNC void STDCALL MD2_Final(uint8_t *digest, MD2_CTX *ctx); - -/************************************************************************** - * MD5 declarations - **************************************************************************/ - -#define MD5_SIZE 16 - -typedef struct -{ - uint32_t state[4]; /* state (ABCD) */ - uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ - uint8_t buffer[64]; /* input buffer */ -} MD5_CTX; - -EXP_FUNC void STDCALL MD5_Init(MD5_CTX *); -EXP_FUNC void STDCALL MD5_Update(MD5_CTX *, const uint8_t *msg, int len); -EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *); - -/************************************************************************** - * HMAC declarations - **************************************************************************/ -void ssl_hmac_md5(const uint8_t *msg, int length, const uint8_t *key, - int key_len, uint8_t *digest);// fix hmac_md5 to ssl_hmac_md5, discriminate ieee80211 -void ssl_hmac_sha1(const uint8_t *msg, int length, const uint8_t *key, - int key_len, uint8_t *digest);// fix hmac_md5 to ssl_hmac_sha1, discriminate ieee80211 - -/************************************************************************** - * RSA declarations - **************************************************************************/ - -typedef struct -{ - bigint *m; /* modulus */ - bigint *e; /* public exponent */ - bigint *d; /* private exponent */ -#ifdef CONFIG_BIGINT_CRT - bigint *p; /* p as in m = pq */ - bigint *q; /* q as in m = pq */ - bigint *dP; /* d mod (p-1) */ - bigint *dQ; /* d mod (q-1) */ - bigint *qInv; /* q^-1 mod p */ -#endif - int num_octets; - BI_CTX *bi_ctx; -} RSA_CTX; - -void RSA_priv_key_new(RSA_CTX **rsa_ctx, - const uint8_t *modulus, int mod_len, - const uint8_t *pub_exp, int pub_len, - const uint8_t *priv_exp, int priv_len -#ifdef CONFIG_BIGINT_CRT - , const uint8_t *p, int p_len, - const uint8_t *q, int q_len, - const uint8_t *dP, int dP_len, - const uint8_t *dQ, int dQ_len, - const uint8_t *qInv, int qInv_len -#endif - ); -void RSA_pub_key_new(RSA_CTX **rsa_ctx, - const uint8_t *modulus, int mod_len, - const uint8_t *pub_exp, int pub_len); -void RSA_free(RSA_CTX *ctx); -int RSA_decrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint8_t *out_data, - int is_decryption); -bigint *RSA_private(const RSA_CTX *c, bigint *bi_msg); -#if defined(CONFIG_SSL_CERT_VERIFICATION) || defined(CONFIG_SSL_GENERATE_X509_CERT) -bigint *RSA_sign_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len, - bigint *modulus, bigint *pub_exp); -bigint *RSA_public(const RSA_CTX * c, bigint *bi_msg); -int RSA_encrypt(const RSA_CTX *ctx, const uint8_t *in_data, uint16_t in_len, - uint8_t *out_data, int is_signing); -void RSA_print(const RSA_CTX *ctx); -#endif - -/************************************************************************** - * RNG declarations - **************************************************************************/ -EXP_FUNC void STDCALL RNG_initialize(void); -EXP_FUNC void STDCALL RNG_custom_init(const uint8_t *seed_buf, int size); -EXP_FUNC void STDCALL RNG_terminate(void); -EXP_FUNC void STDCALL get_random(int num_rand_bytes, uint8_t *rand_data); -void get_random_NZ(int num_rand_bytes, uint8_t *rand_data); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/ssl/ssl_crypto_misc.h b/include/ssl/ssl_crypto_misc.h deleted file mode 100644 index 8e1ba53..0000000 --- a/include/ssl/ssl_crypto_misc.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2007, Cameron Rich - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/** - * @file crypto_misc.h - */ - -#ifndef HEADER_CRYPTO_MISC_H -#define HEADER_CRYPTO_MISC_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "ssl/ssl_crypto.h" -#include "ssl/ssl_bigint.h" - -/************************************************************************** - * X509 declarations - **************************************************************************/ -#define X509_OK 0 -#define X509_NOT_OK -1 -#define X509_VFY_ERROR_NO_TRUSTED_CERT -2 -#define X509_VFY_ERROR_BAD_SIGNATURE -3 -#define X509_VFY_ERROR_NOT_YET_VALID -4 -#define X509_VFY_ERROR_EXPIRED -5 -#define X509_VFY_ERROR_SELF_SIGNED -6 -#define X509_VFY_ERROR_INVALID_CHAIN -7 -#define X509_VFY_ERROR_UNSUPPORTED_DIGEST -8 -#define X509_INVALID_PRIV_KEY -9 - -/* - * The Distinguished Name - */ -#define X509_NUM_DN_TYPES 3 -#define X509_COMMON_NAME 0 -#define X509_ORGANIZATION 1 -#define X509_ORGANIZATIONAL_UNIT 2 - -struct _x509_ctx -{ - char *ca_cert_dn[X509_NUM_DN_TYPES]; - char *cert_dn[X509_NUM_DN_TYPES]; - char **subject_alt_dnsnames; - time_t not_before; - time_t not_after; - uint8_t *signature; - uint16_t sig_len; - uint8_t sig_type; - RSA_CTX *rsa_ctx; - bigint *digest; - struct _x509_ctx *next; -}; - -typedef struct _x509_ctx X509_CTX; - -#ifdef CONFIG_SSL_CERT_VERIFICATION -typedef struct -{ - X509_CTX *cert[CONFIG_X509_MAX_CA_CERTS]; -} CA_CERT_CTX; -#endif - -int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx); -void x509_free(X509_CTX *x509_ctx); -#ifdef CONFIG_SSL_CERT_VERIFICATION -int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert); -#endif -#ifdef CONFIG_SSL_FULL_MODE -void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx); -const char * x509_display_error(int error); -#endif - -/************************************************************************** - * ASN1 declarations - **************************************************************************/ -#define ASN1_INTEGER 0x02 -#define ASN1_BIT_STRING 0x03 -#define ASN1_OCTET_STRING 0x04 -#define ASN1_NULL 0x05 -#define ASN1_PRINTABLE_STR2 0x0C -#define ASN1_OID 0x06 -#define ASN1_PRINTABLE_STR2 0x0C -#define ASN1_PRINTABLE_STR 0x13 -#define ASN1_TELETEX_STR 0x14 -#define ASN1_IA5_STR 0x16 -#define ASN1_UTC_TIME 0x17 -#define ASN1_UNICODE_STR 0x1e -#define ASN1_SEQUENCE 0x30 -#define ASN1_CONTEXT_DNSNAME 0x82 -#define ASN1_SET 0x31 -#define ASN1_V3_DATA 0xa3 -#define ASN1_IMPLICIT_TAG 0x80 -#define ASN1_CONTEXT_DNSNAME 0x82 -#define ASN1_EXPLICIT_TAG 0xa0 -#define ASN1_V3_DATA 0xa3 - -#define SIG_TYPE_MD2 0x02 -#define SIG_TYPE_MD5 0x04 -#define SIG_TYPE_SHA1 0x05 - -int get_asn1_length(const uint8_t *buf, int *offset); -int asn1_get_private_key(const uint8_t *buf, int len, RSA_CTX **rsa_ctx); -int asn1_next_obj(const uint8_t *buf, int *offset, int obj_type); -int asn1_skip_obj(const uint8_t *buf, int *offset, int obj_type); -int asn1_get_int(const uint8_t *buf, int *offset, uint8_t **object); -int asn1_version(const uint8_t *cert, int *offset, X509_CTX *x509_ctx); -int asn1_validity(const uint8_t *cert, int *offset, X509_CTX *x509_ctx); -int asn1_name(const uint8_t *cert, int *offset, char *dn[]); -int asn1_public_key(const uint8_t *cert, int *offset, X509_CTX *x509_ctx); -#ifdef CONFIG_SSL_CERT_VERIFICATION -int asn1_signature(const uint8_t *cert, int *offset, X509_CTX *x509_ctx); -int asn1_find_subjectaltname(const uint8_t* cert, int offset); -int asn1_compare_dn(char * const dn1[], char * const dn2[]); -#endif /* CONFIG_SSL_CERT_VERIFICATION */ -int asn1_signature_type(const uint8_t *cert, - int *offset, X509_CTX *x509_ctx); - -/************************************************************************** - * MISC declarations - **************************************************************************/ -#define SALT_SIZE 8 - -extern const char * const unsupported_str; - -typedef void (*crypt_func)(void *, const uint8_t *, uint8_t *, int); -typedef void (*hmac_func)(const uint8_t *msg, int length, const uint8_t *key, - int key_len, uint8_t *digest); - -int get_file(const char *filename, uint8_t **buf); - -#if defined(CONFIG_SSL_FULL_MODE) || defined(WIN32) || defined(CONFIG_DEBUG) -EXP_FUNC void STDCALL print_blob(const char *format, const uint8_t *data, int size, ...); -#else - #define print_blob(...) -#endif - -EXP_FUNC int STDCALL base64_decode(const char *in, int len, - uint8_t *out, int *outlen); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/ssl/ssl_ssl.h b/include/ssl/ssl_ssl.h deleted file mode 100644 index 4564533..0000000 --- a/include/ssl/ssl_ssl.h +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Copyright (c) 2007, Cameron Rich - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @mainpage axTLS API - * - * @image html axolotl.jpg - * - * The axTLS library has features such as: - * - The TLSv1 SSL client/server protocol - * - No requirement to use any openssl libraries. - * - A choice between AES block (128/256 bit) and RC4 (128 bit) stream ciphers. - * - RSA encryption/decryption with variable sized keys (up to 4096 bits). - * - Certificate chaining and peer authentication. - * - Session resumption, session renegotiation. - * - ASN.1, X.509, PKCS#8, PKCS#12 keys/certificates with DER/PEM encoding. - * - Highly configurable compile time options. - * - Portable across many platforms (written in ANSI C), and has language - * bindings in C, C#, VB.NET, Java, Perl and Lua. - * - Partial openssl API compatibility (via a wrapper). - * - A very small footprint (around 50-60kB for the library in 'server-only' - * mode). - * - No dependencies on sockets - can use serial connections for example. - * - A very simple API - ~ 20 functions/methods. - * - * A list of these functions/methods are described below. - * - * @ref c_api - * - * @ref bigint_api - * - * @ref csharp_api - * - * @ref java_api - */ -#ifndef HEADER_SSL_H -#define HEADER_SSL_H - -#ifdef __cplusplus -extern "C" { -#endif - -//#include <time.h> -typedef long time_t; - -/* need to predefine before ssl_lib.h gets to it */ -#define SSL_SESSION_ID_SIZE 32 - -#include "ssl/ssl_tls1.h" - -/* The optional parameters that can be given to the client/server SSL engine */ -#define SSL_CLIENT_AUTHENTICATION 0x00010000 -#define SSL_SERVER_VERIFY_LATER 0x00020000 -#define SSL_NO_DEFAULT_KEY 0x00040000 -#define SSL_DISPLAY_STATES 0x00080000 -#define SSL_DISPLAY_BYTES 0x00100000 -#define SSL_DISPLAY_CERTS 0x00200000 -#define SSL_DISPLAY_RSA 0x00400000 -#define SSL_CONNECT_IN_PARTS 0x00800000 - -/* errors that can be generated */ -#define SSL_OK 0 -#define SSL_NOT_OK -1 -#define SSL_ERROR_DEAD -2 -#define SSL_CLOSE_NOTIFY -3 -#define SSL_ERROR_CONN_LOST -256 -#define SSL_ERROR_SOCK_SETUP_FAILURE -258 -#define SSL_ERROR_INVALID_HANDSHAKE -260 -#define SSL_ERROR_INVALID_PROT_MSG -261 -#define SSL_ERROR_INVALID_HMAC -262 -#define SSL_ERROR_INVALID_VERSION -263 -#define SSL_ERROR_INVALID_SESSION -265 -#define SSL_ERROR_NO_CIPHER -266 -#define SSL_ERROR_BAD_CERTIFICATE -268 -#define SSL_ERROR_INVALID_KEY -269 -#define SSL_ERROR_FINISHED_INVALID -271 -#define SSL_ERROR_NO_CERT_DEFINED -272 -#define SSL_ERROR_NO_CLIENT_RENOG -273 -#define SSL_ERROR_NOT_SUPPORTED -274 -#define SSL_X509_OFFSET -512 -#define SSL_X509_ERROR(A) (SSL_X509_OFFSET+A) - -/* alert types that are recognized */ -#define SSL_ALERT_TYPE_WARNING 1 -#define SLL_ALERT_TYPE_FATAL 2 - -/* these are all the alerts that are recognized */ -#define SSL_ALERT_CLOSE_NOTIFY 0 -#define SSL_ALERT_UNEXPECTED_MESSAGE 10 -#define SSL_ALERT_BAD_RECORD_MAC 20 -#define SSL_ALERT_HANDSHAKE_FAILURE 40 -#define SSL_ALERT_BAD_CERTIFICATE 42 -#define SSL_ALERT_ILLEGAL_PARAMETER 47 -#define SSL_ALERT_DECODE_ERROR 50 -#define SSL_ALERT_DECRYPT_ERROR 51 -#define SSL_ALERT_INVALID_VERSION 70 -#define SSL_ALERT_NO_RENEGOTIATION 100 - -/* The ciphers that are supported */ -#define SSL_AES128_SHA 0x2f -#define SSL_AES256_SHA 0x35 -#define SSL_RC4_128_SHA 0x05 -#define SSL_RC4_128_MD5 0x04 - -/* build mode ids' */ -#define SSL_BUILD_SKELETON_MODE 0x01 -#define SSL_BUILD_SERVER_ONLY 0x02 -#define SSL_BUILD_ENABLE_VERIFICATION 0x03 -#define SSL_BUILD_ENABLE_CLIENT 0x04 -#define SSL_BUILD_FULL_MODE 0x05 - -/* offsets to retrieve configuration information */ -#define SSL_BUILD_MODE 0 -#define SSL_MAX_CERT_CFG_OFFSET 1 -#define SSL_MAX_CA_CERT_CFG_OFFSET 2 -#define SSL_HAS_PEM 3 - -/* default session sizes */ -#define SSL_DEFAULT_SVR_SESS 1 //modify 5->1 by lhan -#define SSL_DEFAULT_CLNT_SESS 1 - -/* X.509/X.520 distinguished name types */ -#define SSL_X509_CERT_COMMON_NAME 0 -#define SSL_X509_CERT_ORGANIZATION 1 -#define SSL_X509_CERT_ORGANIZATIONAL_NAME 2 -#define SSL_X509_CA_CERT_COMMON_NAME 3 -#define SSL_X509_CA_CERT_ORGANIZATION 4 -#define SSL_X509_CA_CERT_ORGANIZATIONAL_NAME 5 - -/* SSL object loader types */ -#define SSL_OBJ_X509_CERT 1 -#define SSL_OBJ_X509_CACERT 2 -#define SSL_OBJ_RSA_KEY 3 -#define SSL_OBJ_PKCS8 4 -#define SSL_OBJ_PKCS12 5 - -/** - * @defgroup c_api Standard C API - * @brief The standard interface in C. - * @{ - */ - -/** - * @brief Establish a new client/server context. - * - * This function is called before any client/server SSL connections are made. - * - * Each new connection will use the this context's private key and - * certificate chain. If a different certificate chain is required, then a - * different context needs to be be used. - * - * There are two threading models supported - a single thread with one - * SSL_CTX can support any number of SSL connections - and multiple threads can - * support one SSL_CTX object each (the default). But if a single SSL_CTX - * object uses many SSL objects in individual threads, then the - * CONFIG_SSL_CTX_MUTEXING option needs to be configured. - * - * @param options [in] Any particular options. At present the options - * supported are: - * - SSL_SERVER_VERIFY_LATER (client only): Don't stop a handshake if the server - * authentication fails. The certificate can be authenticated later with a - * call to ssl_verify_cert(). - * - SSL_CLIENT_AUTHENTICATION (server only): Enforce client authentication - * i.e. each handshake will include a "certificate request" message from the - * server. Only available if verification has been enabled. - * - SSL_DISPLAY_BYTES (full mode build only): Display the byte sequences - * during the handshake. - * - SSL_DISPLAY_STATES (full mode build only): Display the state changes - * during the handshake. - * - SSL_DISPLAY_CERTS (full mode build only): Display the certificates that - * are passed during a handshake. - * - SSL_DISPLAY_RSA (full mode build only): Display the RSA key details that - * are passed during a handshake. - * - SSL_CONNECT_IN_PARTS (client only): To use a non-blocking version of - * ssl_client_new(). - * @param num_sessions [in] The number of sessions to be used for session - * caching. If this value is 0, then there is no session caching. This option - * is not used in skeleton mode. - * @return A client/server context. - */ -EXP_FUNC SSL_CTX * STDCALL ssl_ctx_new(uint32_t options, int num_sessions); - -/** - * @brief Remove a client/server context. - * - * Frees any used resources used by this context. Each connection will be - * sent a "Close Notify" alert (if possible). - * @param ssl_ctx [in] The client/server context. - */ -EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx); - -/** - * @brief (server only) Establish a new SSL connection to an SSL client. - * - * It is up to the application to establish the logical connection (whether it - * is a socket, serial connection etc). - * @param ssl_ctx [in] The server context. - * @param client_fd [in] The client's file descriptor. - * @return An SSL object reference. - */ -EXP_FUNC SSL * STDCALL ssl_server_new(SSL_CTX *ssl_ctx, int client_fd); - -/** - * @brief (client only) Establish a new SSL connection to an SSL server. - * - * It is up to the application to establish the initial logical connection - * (whether it is a socket, serial connection etc). - * - * This is a normally a blocking call - it will finish when the handshake is - * complete (or has failed). To use in non-blocking mode, set - * SSL_CONNECT_IN_PARTS in ssl_ctx_new(). - * @param ssl_ctx [in] The client context. - * @param client_fd [in] The client's file descriptor. - * @param session_id [in] A 32 byte session id for session resumption. This - * can be null if no session resumption is being used or required. This option - * is not used in skeleton mode. - * @param sess_id_size The size of the session id (max 32) - * @return An SSL object reference. Use ssl_handshake_status() to check - * if a handshake succeeded. - */ -EXP_FUNC SSL * STDCALL ssl_client_new(SSL_CTX *ssl_ctx, int client_fd, const uint8_t *session_id, uint8_t sess_id_size); - -/** - * @brief Free any used resources on this connection. - - * A "Close Notify" message is sent on this connection (if possible). It is up - * to the application to close the socket or file descriptor. - * @param ssl [in] The ssl object reference. - */ -EXP_FUNC void STDCALL ssl_free(SSL *ssl); - -/** - * @brief Read the SSL data stream. - * If the socket is non-blocking and data is blocked then SSO_OK will be - * returned. - * @param ssl [in] An SSL object reference. - * @param in_data [out] If the read was successful, a pointer to the read - * buffer will be here. Do NOT ever free this memory as this buffer is used in - * sucessive calls. If the call was unsuccessful, this value will be null. - * @return The number of decrypted bytes: - * - if > 0, then the handshaking is complete and we are returning the number - * of decrypted bytes. - * - SSL_OK if the handshaking stage is successful (but not yet complete). - * - < 0 if an error. - * @see ssl.h for the error code list. - * @note Use in_data before doing any successive ssl calls. - */ -EXP_FUNC int STDCALL ssl_read(SSL *ssl, uint8_t **in_data); - -/** - * @brief Write to the SSL data stream. - * if the socket is non-blocking and data is blocked then a check is made - * to ensure that all data is sent (i.e. blocked mode is forced). - * @param ssl [in] An SSL obect reference. - * @param out_data [in] The data to be written - * @param out_len [in] The number of bytes to be written. - * @return The number of bytes sent, or if < 0 if an error. - * @see ssl.h for the error code list. - */ -EXP_FUNC int STDCALL ssl_write(SSL *ssl, const uint8_t *out_data, int out_len); - -/** - * @brief Find an ssl object based on a file descriptor. - * - * Goes through the list of SSL objects maintained in a client/server context - * to look for a file descriptor match. - * @param ssl_ctx [in] The client/server context. - * @param client_fd [in] The file descriptor. - * @return A reference to the SSL object. Returns null if the object could not - * be found. - */ -EXP_FUNC SSL * STDCALL ssl_find(SSL_CTX *ssl_ctx, int client_fd); - -/** - * @brief Get the session id for a handshake. - * - * This will be a 32 byte sequence and is available after the first - * handshaking messages are sent. - * @param ssl [in] An SSL object reference. - * @return The session id as a 32 byte sequence. - * @note A SSLv23 handshake may have only 16 valid bytes. - */ -EXP_FUNC const uint8_t * STDCALL ssl_get_session_id(const SSL *ssl); - -/** - * @brief Get the session id size for a handshake. - * - * This will normally be 32 but could be 0 (no session id) or something else. - * @param ssl [in] An SSL object reference. - * @return The size of the session id. - */ -EXP_FUNC uint8_t STDCALL ssl_get_session_id_size(const SSL *ssl); - -/** - * @brief Return the cipher id (in the SSL form). - * @param ssl [in] An SSL object reference. - * @return The cipher id. This will be one of the following: - * - SSL_AES128_SHA (0x2f) - * - SSL_AES256_SHA (0x35) - * - SSL_RC4_128_SHA (0x05) - * - SSL_RC4_128_MD5 (0x04) - */ -EXP_FUNC uint8_t STDCALL ssl_get_cipher_id(const SSL *ssl); - -/** - * @brief Return the status of the handshake. - * @param ssl [in] An SSL object reference. - * @return SSL_OK if the handshake is complete and ok. - * @see ssl.h for the error code list. - */ -EXP_FUNC int STDCALL ssl_handshake_status(const SSL *ssl); - -/** - * @brief Retrieve various parameters about the axTLS engine. - * @param offset [in] The configuration offset. It will be one of the following: - * - SSL_BUILD_MODE The build mode. This will be one of the following: - * - SSL_BUILD_SERVER_ONLY (basic server mode) - * - SSL_BUILD_ENABLE_VERIFICATION (server can do client authentication) - * - SSL_BUILD_ENABLE_CLIENT (client/server capabilties) - * - SSL_BUILD_FULL_MODE (client/server with diagnostics) - * - SSL_BUILD_SKELETON_MODE (skeleton mode) - * - SSL_MAX_CERT_CFG_OFFSET The maximum number of certificates allowed. - * - SSL_MAX_CA_CERT_CFG_OFFSET The maximum number of CA certificates allowed. - * - SSL_HAS_PEM 1 if supported - * @return The value of the requested parameter. - */ -EXP_FUNC int STDCALL ssl_get_config(int offset); - -/** - * @brief Display why the handshake failed. - * - * This call is only useful in a 'full mode' build. The output is to stdout. - * @param error_code [in] An error code. - * @see ssl.h for the error code list. - */ -//EXP_FUNC void STDCALL ssl_display_error(int error_code); - -/** - * @brief Authenticate a received certificate. - * - * This call is usually made by a client after a handshake is complete and the - * context is in SSL_SERVER_VERIFY_LATER mode. - * @param ssl [in] An SSL object reference. - * @return SSL_OK if the certificate is verified. - */ -EXP_FUNC int STDCALL ssl_verify_cert(const SSL *ssl); - -/** - * @brief Retrieve an X.509 distinguished name component. - * - * When a handshake is complete and a certificate has been exchanged, then the - * details of the remote certificate can be retrieved. - * - * This will usually be used by a client to check that the server's common - * name matches the URL. - * - * @param ssl [in] An SSL object reference. - * @param component [in] one of: - * - SSL_X509_CERT_COMMON_NAME - * - SSL_X509_CERT_ORGANIZATION - * - SSL_X509_CERT_ORGANIZATIONAL_NAME - * - SSL_X509_CA_CERT_COMMON_NAME - * - SSL_X509_CA_CERT_ORGANIZATION - * - SSL_X509_CA_CERT_ORGANIZATIONAL_NAME - * @return The appropriate string (or null if not defined) - * @note Verification build mode must be enabled. - */ -EXP_FUNC const char * STDCALL ssl_get_cert_dn(const SSL *ssl, int component); - -/** - * @brief Retrieve a Subject Alternative DNSName - * - * When a handshake is complete and a certificate has been exchanged, then the - * details of the remote certificate can be retrieved. - * - * This will usually be used by a client to check that the server's DNS - * name matches the URL. - * - * @param ssl [in] An SSL object reference. - * @param dnsindex [in] The index of the DNS name to retrieve. - * @return The appropriate string (or null if not defined) - * @note Verification build mode must be enabled. - */ -EXP_FUNC const char * STDCALL ssl_get_cert_subject_alt_dnsname(const SSL *ssl, int dnsindex); - -/** - * @brief Force the client to perform its handshake again. - * - * For a client this involves sending another "client hello" message. - * For the server is means sending a "hello request" message. - * - * This is a blocking call on the client (until the handshake completes). - * - * @param ssl [in] An SSL object reference. - * @return SSL_OK if renegotiation instantiation was ok - */ -EXP_FUNC int STDCALL ssl_renegotiate(SSL *ssl); - -/** - * @brief Process a file that is in binary DER or ASCII PEM format. - * - * These are temporary objects that are used to load private keys, - * certificates etc into memory. - * @param ssl_ctx [in] The client/server context. - * @param obj_type [in] The format of the file. Can be one of: - * - SSL_OBJ_X509_CERT (no password required) - * - SSL_OBJ_X509_CACERT (no password required) - * - SSL_OBJ_RSA_KEY (AES128/AES256 PEM encryption supported) - * - SSL_OBJ_PKCS8 (RC4-128 encrypted data supported) - * - SSL_OBJ_PKCS12 (RC4-128 encrypted data supported) - * - * PEM files are automatically detected (if supported). The object type is - * also detected, and so is not relevant for these types of files. - * @param filename [in] The location of a file in DER/PEM format. - * @param password [in] The password used. Can be null if not required. - * @return SSL_OK if all ok - * @note Not available in skeleton build mode. - */ -EXP_FUNC int STDCALL ssl_obj_load(SSL_CTX *ssl_ctx, int obj_type, const char *filename, const char *password); - -/** - * @brief Process binary data. - * - * These are temporary objects that are used to load private keys, - * certificates etc into memory. - * @param ssl_ctx [in] The client/server context. - * @param obj_type [in] The format of the memory data. - * @param data [in] The binary data to be loaded. - * @param len [in] The amount of data to be loaded. - * @param password [in] The password used. Can be null if not required. - * @return SSL_OK if all ok - * @see ssl_obj_load for more details on obj_type. - */ -EXP_FUNC int STDCALL ssl_obj_memory_load(SSL_CTX *ssl_ctx, int obj_type, const uint8_t *data, int len, const char *password); - -#ifdef CONFIG_SSL_GENERATE_X509_CERT -/** - * @brief Create an X.509 certificate. - * - * This certificate is a self-signed v1 cert with a fixed start/stop validity - * times. It is signed with an internal private key in ssl_ctx. - * - * @param ssl_ctx [in] The client/server context. - * @param options [in] Not used yet. - * @param dn [in] An array of distinguished name strings. The array is defined - * by: - * - SSL_X509_CERT_COMMON_NAME (0) - * - If SSL_X509_CERT_COMMON_NAME is empty or not defined, then the - * hostname will be used. - * - SSL_X509_CERT_ORGANIZATION (1) - * - If SSL_X509_CERT_ORGANIZATION is empty or not defined, then $USERNAME - * will be used. - * - SSL_X509_CERT_ORGANIZATIONAL_NAME (2) - * - SSL_X509_CERT_ORGANIZATIONAL_NAME is optional. - * @param cert_data [out] The certificate as a sequence of bytes. - * @return < 0 if an error, or the size of the certificate in bytes. - * @note cert_data must be freed when there is no more need for it. - */ -EXP_FUNC int STDCALL ssl_x509_create(SSL_CTX *ssl_ctx, uint32_t options, const char * dn[], uint8_t **cert_data); -#endif - -/** - * @brief Return the axTLS library version as a string. - */ -EXP_FUNC const char * STDCALL ssl_version(void); - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/ssl/ssl_tls1.h b/include/ssl/ssl_tls1.h deleted file mode 100644 index 5597856..0000000 --- a/include/ssl/ssl_tls1.h +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Copyright (c) 2007, Cameron Rich - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * * Neither the name of the axTLS project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/** - * @file tls1.h - * - * @brief The definitions for the TLS library. - */ -#ifndef HEADER_SSL_LIB_H -#define HEADER_SSL_LIB_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "c_types.h" -#include "ssl/ssl_version.h" -#include "ssl/ssl_config.h" - -#include "ssl/ssl_crypto.h" -#include "ssl/ssl_crypto_misc.h" - -#define SSL_PROTOCOL_MIN_VERSION 0x31 /* TLS v1.0 */ -#define SSL_PROTOCOL_MINOR_VERSION 0x02 /* TLS v1.1 */ -#define SSL_PROTOCOL_VERSION_MAX 0x32 /* TLS v1.1 */ -#define SSL_PROTOCOL_VERSION1_1 0x32 /* TLS v1.1 */ -#define SSL_RANDOM_SIZE 32 -#define SSL_SECRET_SIZE 48 -#define SSL_FINISHED_HASH_SIZE 12 -#define SSL_RECORD_SIZE 5 -#define SSL_SERVER_READ 0 -#define SSL_SERVER_WRITE 1 -#define SSL_CLIENT_READ 2 -#define SSL_CLIENT_WRITE 3 -#define SSL_HS_HDR_SIZE 4 - -/* the flags we use while establishing a connection */ -#define SSL_NEED_RECORD 0x0001 -#define SSL_TX_ENCRYPTED 0x0002 -#define SSL_RX_ENCRYPTED 0x0004 -#define SSL_SESSION_RESUME 0x0008 -#define SSL_IS_CLIENT 0x0010 -#define SSL_HAS_CERT_REQ 0x0020 -#define SSL_SENT_CLOSE_NOTIFY 0x0040 - -/* some macros to muck around with flag bits */ -#define SET_SSL_FLAG(A) (ssl->flag |= A) -#define CLR_SSL_FLAG(A) (ssl->flag &= ~A) -#define IS_SET_SSL_FLAG(A) (ssl->flag & A) - -#define MAX_KEY_BYTE_SIZE 512 /* for a 4096 bit key */ -#define RT_MAX_PLAIN_LENGTH 1024 -#define RT_EXTRA 1024 -#define BM_RECORD_OFFSET 5 - -#ifdef CONFIG_SSL_SKELETON_MODE -#define NUM_PROTOCOLS 1 -#else -#define NUM_PROTOCOLS 4 -#endif - -#define PARANOIA_CHECK(A, B) if (A < B) { \ - ret = SSL_ERROR_INVALID_HANDSHAKE; goto error; } - -/* protocol types */ -enum -{ - PT_CHANGE_CIPHER_SPEC = 20, - PT_ALERT_PROTOCOL, - PT_HANDSHAKE_PROTOCOL, - PT_APP_PROTOCOL_DATA -}; - -/* handshaking types */ -enum -{ - HS_HELLO_REQUEST, - HS_CLIENT_HELLO, - HS_SERVER_HELLO, - HS_CERTIFICATE = 11, - HS_SERVER_KEY_XCHG, - HS_CERT_REQ, - HS_SERVER_HELLO_DONE, - HS_CERT_VERIFY, - HS_CLIENT_KEY_XCHG, - HS_FINISHED = 20 -}; - -typedef struct -{ - uint8_t cipher; - uint8_t key_size; - uint8_t iv_size; - uint8_t key_block_size; - uint8_t padding_size; - uint8_t digest_size; - hmac_func hmac; - crypt_func encrypt; - crypt_func decrypt; -} cipher_info_t; - -struct _SSLObjLoader -{ - uint8_t *buf; - int len; -}; - -typedef struct _SSLObjLoader SSLObjLoader; - -typedef struct -{ - time_t conn_time; - uint8_t session_id[SSL_SESSION_ID_SIZE]; - uint8_t master_secret[SSL_SECRET_SIZE]; -} SSL_SESSION; - -typedef struct -{ - uint8_t *buf; - int size; -} SSL_CERT; - -typedef struct -{ - MD5_CTX md5_ctx; - SHA1_CTX sha1_ctx; - uint8_t final_finish_mac[SSL_FINISHED_HASH_SIZE]; - uint8_t *key_block; - uint8_t master_secret[SSL_SECRET_SIZE]; - uint8_t client_random[SSL_RANDOM_SIZE]; /* client's random sequence */ - uint8_t server_random[SSL_RANDOM_SIZE]; /* server's random sequence */ - uint16_t bm_proc_index; -} DISPOSABLE_CTX; - -struct _SSL -{ - uint32_t flag; - uint16_t need_bytes; - uint16_t got_bytes; - uint8_t record_type; - uint8_t cipher; - uint8_t sess_id_size; - uint8_t version; - uint8_t client_version; - sint16_t next_state; - sint16_t hs_status; - DISPOSABLE_CTX *dc; /* temporary data which we'll get rid of soon */ - int client_fd; - const cipher_info_t *cipher_info; - void *encrypt_ctx; - void *decrypt_ctx; - uint8_t bm_all_data[RT_MAX_PLAIN_LENGTH+RT_EXTRA]; - uint8_t *bm_data; - uint16_t bm_index; - uint16_t bm_read_index; - struct _SSL *next; /* doubly linked list */ - struct _SSL *prev; - struct _SSL_CTX *ssl_ctx; /* back reference to a clnt/svr ctx */ -#ifndef CONFIG_SSL_SKELETON_MODE - uint16_t session_index; - SSL_SESSION *session; -#endif -#ifdef CONFIG_SSL_CERT_VERIFICATION - X509_CTX *x509_ctx; -#endif - - uint8_t session_id[SSL_SESSION_ID_SIZE]; - uint8_t client_mac[SHA1_SIZE]; /* for HMAC verification */ - uint8_t server_mac[SHA1_SIZE]; /* for HMAC verification */ - uint8_t read_sequence[8]; /* 64 bit sequence number */ - uint8_t write_sequence[8]; /* 64 bit sequence number */ - uint8_t hmac_header[SSL_RECORD_SIZE]; /* rx hmac */ -}; - -typedef struct _SSL SSL; - -struct _SSL_CTX -{ - uint32_t options; - uint8_t chain_length; - RSA_CTX *rsa_ctx; -#ifdef CONFIG_SSL_CERT_VERIFICATION - CA_CERT_CTX *ca_cert_ctx; -#endif - SSL *head; - SSL *tail; - SSL_CERT certs[CONFIG_SSL_MAX_CERTS]; -#ifndef CONFIG_SSL_SKELETON_MODE - uint16_t num_sessions; - SSL_SESSION **ssl_sessions; -#endif -#ifdef CONFIG_SSL_CTX_MUTEXING - SSL_CTX_MUTEX_TYPE mutex; -#endif -#ifdef CONFIG_OPENSSL_COMPATIBLE - void *bonus_attr; -#endif -}; - -typedef struct _SSL_CTX SSL_CTX; - -/* backwards compatibility */ -typedef struct _SSL_CTX SSLCTX; - -extern const uint8_t ssl_prot_prefs[NUM_PROTOCOLS]; - -SSL *ssl_new(SSL_CTX *ssl_ctx, int client_fd); -void disposable_new(SSL *ssl); -void disposable_free(SSL *ssl); -int send_packet(SSL *ssl, uint8_t protocol, - const uint8_t *in, int length); -int do_svr_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len); -int do_clnt_handshake(SSL *ssl, int handshake_type, uint8_t *buf, int hs_len); -int process_finished(SSL *ssl, uint8_t *buf, int hs_len); -int process_sslv23_client_hello(SSL *ssl); -int send_alert(SSL *ssl, int error_code); -int send_finished(SSL *ssl); -int send_certificate(SSL *ssl); -int basic_read(SSL *ssl, uint8_t **in_data); -int send_change_cipher_spec(SSL *ssl); -void finished_digest(SSL *ssl, const char *label, uint8_t *digest); -void generate_master_secret(SSL *ssl, const uint8_t *premaster_secret); -void add_packet(SSL *ssl, const uint8_t *pkt, int len); -int add_cert(SSL_CTX *ssl_ctx, const uint8_t *buf, int len); -int add_private_key(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj); -void ssl_obj_free(SSLObjLoader *ssl_obj); -int pkcs8_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password); -int pkcs12_decode(SSL_CTX *ssl_ctx, SSLObjLoader *ssl_obj, const char *password); -int load_key_certs(SSL_CTX *ssl_ctx); -#ifdef CONFIG_SSL_CERT_VERIFICATION -int add_cert_auth(SSL_CTX *ssl_ctx, const uint8_t *buf, int len); -void remove_ca_certs(CA_CERT_CTX *ca_cert_ctx); -#endif -#ifdef CONFIG_SSL_ENABLE_CLIENT -int do_client_connect(SSL *ssl); -#endif - -#ifdef CONFIG_SSL_FULL_MODE -//void DISPLAY_STATE(SSL *ssl, int is_send, uint8_t state, int not_ok); -//void DISPLAY_BYTES(SSL *ssl, const char *format, -// const uint8_t *data, int size, ...); -//void DISPLAY_CERT(SSL *ssl, const X509_CTX *x509_ctx); -//void DISPLAY_RSA(SSL *ssl, const RSA_CTX *rsa_ctx); -//void DISPLAY_ALERT(SSL *ssl, int alert); -#else -#define DISPLAY_STATE(A,B,C,D) -#define DISPLAY_CERT(A,B) -#define DISPLAY_RSA(A,B) -#define DISPLAY_ALERT(A, B) -#ifdef WIN32 -void DISPLAY_BYTES(SSL *ssl, const char *format,/* win32 has no variadic macros */ - const uint8_t *data, int size, ...); -#else -#define DISPLAY_BYTES(A,B,C,D,...) -#endif -#endif - -#ifdef CONFIG_SSL_CERT_VERIFICATION -int process_certificate(SSL *ssl, X509_CTX **x509_ctx); -#endif - -SSL_SESSION *ssl_session_update(int max_sessions, - SSL_SESSION *ssl_sessions[], SSL *ssl, - const uint8_t *session_id); -void kill_ssl_session(SSL_SESSION **ssl_sessions, SSL *ssl); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/ssl/ssl_version.h b/include/ssl/ssl_version.h deleted file mode 100644 index e8158cc..0000000 --- a/include/ssl/ssl_version.h +++ /dev/null @@ -1 +0,0 @@ -#define AXTLS_VERSION "1.4.9" diff --git a/lib/libssl.a b/lib/libssl.a deleted file mode 100644 index 77d9dfaba263280516e6a53a6ab871e4300ada8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 137692 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%0D1#mUbW`WJy&WQ->r%w2fo>0lZ<vL9nSMG#yD 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 aetS6%-<Nb>;roelfwL)fJi+la$NwArT{4FN diff --git a/lib/symbols_norename.txt b/lib/symbols_norename.txt index 8d762b4..766c191 100644 --- a/lib/symbols_norename.txt +++ b/lib/symbols_norename.txt @@ -3,4 +3,6 @@ puts printf putchar +rand +srand atoi diff --git a/lwip/component.mk b/lwip/component.mk index 7f737a6..92e8a36 100644 --- a/lwip/component.mk +++ b/lwip/component.mk @@ -1,7 +1,7 @@ # Component makefile for LWIP LWIP_DIR = $(ROOT)lwip/lwip/src/ -INC_DIRS += $(LWIP_DIR)/include $(ROOT)/lwip/include $(ROOT)lwip/include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip +INC_DIRS += $(LWIP_DIR)include $(ROOT)lwip/include $(ROOT)lwip/include $(LWIP_DIR)include/ipv4 $(LWIP_DIR)include/ipv4/lwip $(LWIP_DIR)include/lwip # args for passing into compile rule generation lwip_ROOT = $(ROOT)/lwip diff --git a/lwip/include/arch/cc.h b/lwip/include/arch/cc.h index fe10d25..acd5f3d 100644 --- a/lwip/include/arch/cc.h +++ b/lwip/include/arch/cc.h @@ -47,6 +47,8 @@ #include <stdio.h> /* printf, fflush, FILE */ #include <stdlib.h> /* abort */ #include <stdint.h> +#include <sys/time.h> +#include <sys/errno.h> #define BYTE_ORDER LITTLE_ENDIAN @@ -59,8 +61,6 @@ #pragma warning (disable: 4103) /* structure packing changed by including file */ #endif -#define LWIP_PROVIDE_ERRNO - /* Define generic types used in lwIP */ typedef uint8_t u8_t; typedef int8_t s8_t; @@ -86,6 +86,7 @@ typedef int sys_prot_t; #define PACK_STRUCT_STRUCT __attribute__( (packed) ) /* Plaform specific diagnostic output */ +#ifdef LWIP_DEBUG #define LWIP_PLATFORM_DIAG(x) do { printf x; } while(0) #define LWIP_PLATFORM_ASSERT(x) do { printf("Assertion \"%s\" failed at line %d in %s\n", \ @@ -94,6 +95,11 @@ typedef int sys_prot_t; #define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ printf("Assertion \"%s\" failed at line %d in %s\n", message, __LINE__, __FILE__); \ handler;} } while(0) +#else +#define LWIP_PLATFORM_DIAG(x) +#define LWIP_PLATFORM_ASSERT(x) +#define LWIP_ERROR(m,e,h) +#endif #define LWIP_PLATFORM_BYTESWAP 1 diff --git a/lwip/include/lwipopts.h b/lwip/include/lwipopts.h index e4b3955..0cdd8d9 100644 --- a/lwip/include/lwipopts.h +++ b/lwip/include/lwipopts.h @@ -1,439 +1,440 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef __LWIPOPTS_H__ -#define __LWIPOPTS_H__ - -#define LWIP_ESP 1 -#define ESP_RTOS 1 -#define PBUF_RSV_FOR_WLAN 1 -#define EBUF_LWIP 1 -#define ESP_TIMEWAIT_THRESHOLD 10000 - -// Uncomment this line, and set the debug options you want below, for IP stack debug output -//#define LWIP_DEBUG - -/* - ----------------------------------------------- - ---------- Platform specific locking ---------- - ----------------------------------------------- -*/ -/** - * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain - * critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#define SYS_LIGHTWEIGHT_PROT 1 - -/** - * MEMCPY: override this if you have a faster implementation at hand than the - * one included in your C library - */ -#define MEMCPY(dst,src,len) memcpy(dst,src,len) - -/** - * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a - * call to memcpy() if the length is known at compile time and is small. - */ -#define SMEMCPY(dst,src,len) memcpy(dst,src,len) - -/* - ------------------------------------ - ---------- Memory options ---------- - ------------------------------------ -*/ -/** - * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library - * instead of the lwip internal allocator. Can save code size if you - * already use it. - */ -#define MEM_LIBC_MALLOC 1 - -/** -* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. -* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution -* speed and usage from interrupts! -*/ -#define MEMP_MEM_MALLOC 1 - -/** - * MEM_ALIGNMENT: should be set to the alignment of the CPU - * 4 byte alignment -> #define MEM_ALIGNMENT 4 - * 2 byte alignment -> #define MEM_ALIGNMENT 2 - */ -#define MEM_ALIGNMENT 4 - -/* - ------------------------------------------------ - ---------- Internal Memory Pool Sizes ---------- - ------------------------------------------------ -*/ - -/* - -------------------------------- - ---------- ARP options ------- - -------------------------------- -*/ -/** - * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address - * resolution. By default, only the most recent packet is queued per IP address. - * This is sufficient for most protocols and mainly reduces TCP connection - * startup time. Set this to 1 if you know your application sends more than one - * packet in a row to an IP address that is not in the ARP cache. - */ -#define ARP_QUEUEING 1 - -/* - -------------------------------- - ---------- IP options ---------- - -------------------------------- -*/ -/** - * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that - * this option does not affect outgoing packet sizes, which can be controlled - * via IP_FRAG. - */ -#define IP_REASSEMBLY 0 - -/** - * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note - * that this option does not affect incoming packet sizes, which can be - * controlled via IP_REASSEMBLY. - */ -#define IP_FRAG 1 - -/** - * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) - * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived - * in this time, the whole packet is discarded. - */ -#define IP_REASS_MAXAGE 3 - -/** - * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. - * Since the received pbufs are enqueued, be sure to configure - * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive - * packets even if the maximum amount of fragments is enqueued for reassembly! - */ -#define IP_REASS_MAX_PBUFS 10 - -/* - ---------------------------------- - ---------- ICMP options ---------- - ---------------------------------- -*/ - -/* - --------------------------------- - ---------- RAW options ---------- - --------------------------------- -*/ - -/* - ---------------------------------- - ---------- DHCP options ---------- - ---------------------------------- -*/ -/** - * LWIP_DHCP==1: Enable DHCP module. - */ -#define LWIP_DHCP 1 - -#define LWIP_DHCP_BOOTP_FILE 0 - -/* - ------------------------------------ - ---------- AUTOIP options ---------- - ------------------------------------ -*/ -/* - ---------------------------------- - ---------- SNMP options ---------- - ---------------------------------- -*/ -/* - ---------------------------------- - ---------- IGMP options ---------- - ---------------------------------- -*/ -/* - ---------------------------------- - ---------- DNS options ----------- - ---------------------------------- -*/ -/** - * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS - * transport. - */ -#define LWIP_DNS 1 - -/* - --------------------------------- - ---------- UDP options ---------- - --------------------------------- -*/ -/* - --------------------------------- - ---------- TCP options ---------- - --------------------------------- -*/ -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#define TCP_QUEUE_OOSEQ 0 - -/* - * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all - * events (accept, sent, etc) that happen in the system. - * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. This is the default. -*/ -#define TCP_MSS 1460 - -/** - * TCP_MAXRTX: Maximum number of retransmissions of data segments. - */ -#define TCP_MAXRTX 6 - - -/** - * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. - */ -#define TCP_SYNMAXRTX 3 - -/* - ---------------------------------- - ---------- Pbuf options ---------- - ---------------------------------- -*/ - -/* - ------------------------------------------------ - ---------- Network Interfaces options ---------- - ------------------------------------------------ -*/ -/** - * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data - * to be sent into one single pbuf. This is for compatibility with DMA-enabled - * MACs that do not support scatter-gather. - * Beware that this might involve CPU-memcpy before transmitting that would not - * be needed without this flag! Use this only if you need to! - * - * @todo: TCP and IP-frag do not work with this, yet: - */ -#define LWIP_NETIF_TX_SINGLE_PBUF 1 - -/* - ------------------------------------ - ---------- LOOPIF options ---------- - ------------------------------------ -*/ - -/* - ------------------------------------ - ---------- SLIPIF options ---------- - ------------------------------------ -*/ - -/* - ------------------------------------ - ---------- Thread options ---------- - ------------------------------------ -*/ -/** - * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#define TCPIP_THREAD_STACKSIZE 512 //not ok:384 - -/** - * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES-5) - -/** - * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when tcpip_init is called. - */ -#define TCPIP_MBOX_SIZE 16 - -/** - * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#define DEFAULT_UDP_RECVMBOX_SIZE 6 - -/** - * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#define DEFAULT_TCP_RECVMBOX_SIZE 6 - -/** - * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when the acceptmbox is created. - */ -#define DEFAULT_ACCEPTMBOX_SIZE 6 - -/* - ---------------------------------------------- - ---------- Sequential layer options ---------- - ---------------------------------------------- -*/ - -/* - ------------------------------------ - ---------- Socket options ---------- - ------------------------------------ -*/ -/** - * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and - * SO_SNDTIMEO processing. - */ -#define LWIP_SO_SNDTIMEO 1 - -/** - * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and - * SO_RCVTIMEO processing. - */ -#define LWIP_SO_RCVTIMEO 1 - -/** - * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT - * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set - * in seconds. (does not require sockets.c, and will affect tcp.c) - */ -#define LWIP_TCP_KEEPALIVE 1 - -/** - * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. - */ -#define LWIP_SO_RCVBUF 0 - -/** - * SO_REUSE==1: Enable SO_REUSEADDR option. - */ -#define SO_REUSE 1 - -/* - ---------------------------------------- - ---------- Statistics options ---------- - ---------------------------------------- -*/ - -/* - --------------------------------- - ---------- PPP options ---------- - --------------------------------- -*/ - -/* - -------------------------------------- - ---------- Checksum options ---------- - -------------------------------------- -*/ - -/* - --------------------------------------- - ---------- IPv6 options --------------- - --------------------------------------- -*/ - -/* - --------------------------------------- - ---------- Hook options --------------- - --------------------------------------- -*/ - -/* - --------------------------------------- - ---------- Debugging options ---------- - --------------------------------------- -*/ -/** - * ETHARP_DEBUG: Enable debugging in etharp.c. - */ -#define ETHARP_DEBUG LWIP_DBG_OFF - -/** - * PBUF_DEBUG: Enable debugging in pbuf.c. - */ -#define PBUF_DEBUG LWIP_DBG_OFF - -/** - * API_LIB_DEBUG: Enable debugging in api_lib.c. - */ -#define API_LIB_DEBUG LWIP_DBG_OFF - -/** - * SOCKETS_DEBUG: Enable debugging in sockets.c. - */ -#define SOCKETS_DEBUG LWIP_DBG_OFF - -/** - * IP_DEBUG: Enable debugging for IP. - */ -#define IP_DEBUG LWIP_DBG_OFF - -/** - * MEMP_DEBUG: Enable debugging in memp.c. - */ -#define MEMP_DEBUG LWIP_DBG_OFF - -/** - * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. - */ -#define TCP_INPUT_DEBUG LWIP_DBG_OFF - -/** - * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. - */ -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF - -/** - * TCPIP_DEBUG: Enable debugging in tcpip.c. - */ -#define TCPIP_DEBUG LWIP_DBG_OFF - -/** - * DHCP_DEBUG: Enable debugging in dhcp.c. - */ -#define DHCP_DEBUG LWIP_DBG_OFF - -#endif /* __LWIPOPTS_H__ */ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Simon Goldschmidt + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#define LWIP_ESP 1 +#define ESP_RTOS 1 +#define PBUF_RSV_FOR_WLAN 1 +#define EBUF_LWIP 1 +#define ESP_TIMEWAIT_THRESHOLD 10000 +#define LWIP_TIMEVAL_PRIVATE 0 + +// Uncomment this line, and set the debug options you want below, for IP stack debug output +//#define LWIP_DEBUG + +/* + ----------------------------------------------- + ---------- Platform specific locking ---------- + ----------------------------------------------- +*/ +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#define SYS_LIGHTWEIGHT_PROT 1 + +/** + * MEMCPY: override this if you have a faster implementation at hand than the + * one included in your C library + */ +#define MEMCPY(dst,src,len) memcpy(dst,src,len) + +/** + * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a + * call to memcpy() if the length is known at compile time and is small. + */ +#define SMEMCPY(dst,src,len) memcpy(dst,src,len) + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ +/** + * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library + * instead of the lwip internal allocator. Can save code size if you + * already use it. + */ +#define MEM_LIBC_MALLOC 1 + +/** +* MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. +* Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution +* speed and usage from interrupts! +*/ +#define MEMP_MEM_MALLOC 1 + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#define MEM_ALIGNMENT 4 + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ + +/* + -------------------------------- + ---------- ARP options ------- + -------------------------------- +*/ +/** + * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address + * resolution. By default, only the most recent packet is queued per IP address. + * This is sufficient for most protocols and mainly reduces TCP connection + * startup time. Set this to 1 if you know your application sends more than one + * packet in a row to an IP address that is not in the ARP cache. + */ +#define ARP_QUEUEING 1 + +/* + -------------------------------- + ---------- IP options ---------- + -------------------------------- +*/ +/** + * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that + * this option does not affect outgoing packet sizes, which can be controlled + * via IP_FRAG. + */ +#define IP_REASSEMBLY 0 + +/** + * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note + * that this option does not affect incoming packet sizes, which can be + * controlled via IP_REASSEMBLY. + */ +#define IP_FRAG 1 + +/** + * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) + * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived + * in this time, the whole packet is discarded. + */ +#define IP_REASS_MAXAGE 3 + +/** + * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. + * Since the received pbufs are enqueued, be sure to configure + * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive + * packets even if the maximum amount of fragments is enqueued for reassembly! + */ +#define IP_REASS_MAX_PBUFS 10 + +/* + ---------------------------------- + ---------- ICMP options ---------- + ---------------------------------- +*/ + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#define LWIP_DHCP 1 + +#define LWIP_DHCP_BOOTP_FILE 0 + +/* + ------------------------------------ + ---------- AUTOIP options ---------- + ------------------------------------ +*/ +/* + ---------------------------------- + ---------- SNMP options ---------- + ---------------------------------- +*/ +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/* + ---------------------------------- + ---------- DNS options ----------- + ---------------------------------- +*/ +/** + * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS + * transport. + */ +#define LWIP_DNS 1 + +/* + --------------------------------- + ---------- UDP options ---------- + --------------------------------- +*/ +/* + --------------------------------- + ---------- TCP options ---------- + --------------------------------- +*/ +/** + * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. + * Define to 0 if your device is low on memory. + */ +#define TCP_QUEUE_OOSEQ 0 + +/* + * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all + * events (accept, sent, etc) that happen in the system. + * LWIP_CALLBACK_API==1: The PCB callback function is called directly + * for the event. This is the default. +*/ +#define TCP_MSS 1460 + +/** + * TCP_MAXRTX: Maximum number of retransmissions of data segments. + */ +#define TCP_MAXRTX 6 + + +/** + * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. + */ +#define TCP_SYNMAXRTX 3 + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data + * to be sent into one single pbuf. This is for compatibility with DMA-enabled + * MACs that do not support scatter-gather. + * Beware that this might involve CPU-memcpy before transmitting that would not + * be needed without this flag! Use this only if you need to! + * + * @todo: TCP and IP-frag do not work with this, yet: + */ +#define LWIP_NETIF_TX_SINGLE_PBUF 1 + +/* + ------------------------------------ + ---------- LOOPIF options ---------- + ------------------------------------ +*/ + +/* + ------------------------------------ + ---------- SLIPIF options ---------- + ------------------------------------ +*/ + +/* + ------------------------------------ + ---------- Thread options ---------- + ------------------------------------ +*/ +/** + * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. + * The stack size value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define TCPIP_THREAD_STACKSIZE 512 //not ok:384 + +/** + * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. + * The priority value itself is platform-dependent, but is passed to + * sys_thread_new() when the thread is created. + */ +#define TCPIP_THREAD_PRIO (configMAX_PRIORITIES-5) + +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#define TCPIP_MBOX_SIZE 16 + +/** + * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_UDP_RECVMBOX_SIZE 6 + +/** + * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a + * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed + * to sys_mbox_new() when the recvmbox is created. + */ +#define DEFAULT_TCP_RECVMBOX_SIZE 6 + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#define DEFAULT_ACCEPTMBOX_SIZE 6 + +/* + ---------------------------------------------- + ---------- Sequential layer options ---------- + ---------------------------------------------- +*/ + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#define LWIP_SO_SNDTIMEO 1 + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#define LWIP_SO_RCVTIMEO 1 + +/** + * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT + * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set + * in seconds. (does not require sockets.c, and will affect tcp.c) + */ +#define LWIP_TCP_KEEPALIVE 1 + +/** + * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. + */ +#define LWIP_SO_RCVBUF 0 + +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#define SO_REUSE 1 + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ + +/* + --------------------------------- + ---------- PPP options ---------- + --------------------------------- +*/ + +/* + -------------------------------------- + ---------- Checksum options ---------- + -------------------------------------- +*/ + +/* + --------------------------------------- + ---------- IPv6 options --------------- + --------------------------------------- +*/ + +/* + --------------------------------------- + ---------- Hook options --------------- + --------------------------------------- +*/ + +/* + --------------------------------------- + ---------- Debugging options ---------- + --------------------------------------- +*/ +/** + * ETHARP_DEBUG: Enable debugging in etharp.c. + */ +#define ETHARP_DEBUG LWIP_DBG_OFF + +/** + * PBUF_DEBUG: Enable debugging in pbuf.c. + */ +#define PBUF_DEBUG LWIP_DBG_OFF + +/** + * API_LIB_DEBUG: Enable debugging in api_lib.c. + */ +#define API_LIB_DEBUG LWIP_DBG_OFF + +/** + * SOCKETS_DEBUG: Enable debugging in sockets.c. + */ +#define SOCKETS_DEBUG LWIP_DBG_OFF + +/** + * IP_DEBUG: Enable debugging for IP. + */ +#define IP_DEBUG LWIP_DBG_OFF + +/** + * MEMP_DEBUG: Enable debugging in memp.c. + */ +#define MEMP_DEBUG LWIP_DBG_OFF + +/** + * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. + */ +#define TCP_INPUT_DEBUG LWIP_DBG_OFF + +/** + * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. + */ +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF + +/** + * TCPIP_DEBUG: Enable debugging in tcpip.c. + */ +#define TCPIP_DEBUG LWIP_DBG_OFF + +/** + * DHCP_DEBUG: Enable debugging in dhcp.c. + */ +#define DHCP_DEBUG LWIP_DBG_OFF + +#endif /* __LWIPOPTS_H__ */