diff --git a/Makefile b/Makefile index 538f340b3..c3f51ac1d 100644 --- a/Makefile +++ b/Makefile @@ -4,8 +4,6 @@ AR := $(TOOLCHAIN_PREFIX)ar LD := $(TOOLCHAIN_PREFIX)gcc OBJCOPY := $(TOOLCHAIN_PREFIX)objcopy -MFORCE32 := $(shell $(CC) --help=target | grep mforce-l32) - XTENSA_LIBS ?= $(shell $(CC) -print-sysroot) @@ -43,13 +41,17 @@ LDFLAGS += -L$(XTENSA_LIBS)/lib \ CFLAGS+=-std=c99 -DESP8266 -CFLAGS += -Wall -Os -g -O2 -Wpointer-arith -Wno-implicit-function-declaration -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mno-text-section-literals -D__ets__ -DICACHE_FLASH +CFLAGS += -Wall -Os -g -O2 -Wpointer-arith -Wl,-EL -nostdlib -mlongcalls -mno-text-section-literals -D__ets__ -DICACHE_FLASH +MFORCE32 := $(shell $(CC) --help=target | grep mforce-l32) ifneq ($(MFORCE32),) - # Your compiler supports the -mforce-l32 flag which means that - # constants can be stored in flash (program) memory instead of SRAM. - # See: https://www.arduino.cc/en/Reference/PROGMEM - CFLAGS += -DPROGMEM="__attribute__((aligned(4))) __attribute__((section(\".irom.text\")))" -mforce-l32 + # If the compiler supports the -mforce-l32 flag, the compiler will generate correct code for loading + # 16- and 8-bit constants from program memory. So in the code we can directly access the arrays + # placed into program memory. + CFLAGS += -mforce-l32 +else + # Otherwise we need to use a helper function to load 16- and 8-bit constants from program memory. + CFLAGS += -DWITH_PGM_READ_HELPER endif BIN_DIR := bin diff --git a/crypto/aes.c b/crypto/aes.c index ba76d301d..af6bd98b7 100644 --- a/crypto/aes.c +++ b/crypto/aes.c @@ -220,20 +220,20 @@ void AES_set_key(AES_CTX *ctx, const uint8_t *key, if ((i % words) == 0) { - tmp2 =(uint32_t)aes_sbox[(tmp )&0xff]<< 8; - tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<<16; - tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<24; - tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]; + tmp2 =(uint32_t)(ax_array_read_u8(aes_sbox, (tmp )&0xff))<< 8; + tmp2|=(uint32_t)(ax_array_read_u8(aes_sbox, (tmp>> 8)&0xff))<<16; + tmp2|=(uint32_t)(ax_array_read_u8(aes_sbox, (tmp>>16)&0xff))<<24; + tmp2|=(uint32_t)(ax_array_read_u8(aes_sbox, (tmp>>24))); tmp=tmp2^(((unsigned int)*ip)<<24); ip++; } if ((words == 8) && ((i % words) == 4)) { - tmp2 =(uint32_t)aes_sbox[(tmp )&0xff] ; - tmp2|=(uint32_t)aes_sbox[(tmp>> 8)&0xff]<< 8; - tmp2|=(uint32_t)aes_sbox[(tmp>>16)&0xff]<<16; - tmp2|=(uint32_t)aes_sbox[(tmp>>24) ]<<24; + tmp2 =(uint32_t)(ax_array_read_u8(aes_sbox, (tmp )&0xff)) ; + tmp2|=(uint32_t)(ax_array_read_u8(aes_sbox, (tmp>> 8)&0xff))<< 8; + tmp2|=(uint32_t)(ax_array_read_u8(aes_sbox, (tmp>>16)&0xff))<<16; + tmp2|=(uint32_t)(ax_array_read_u8(aes_sbox, (tmp>>24) ))<<24; tmp=tmp2; } @@ -369,10 +369,10 @@ static void AES_encrypt(const AES_CTX *ctx, uint32_t *data) /* Perform ByteSub and ShiftRow operations together */ for (row = 0; row < 4; row++) { - a0 = (uint32_t)aes_sbox[(data[row%4]>>24)&0xFF]; - a1 = (uint32_t)aes_sbox[(data[(row+1)%4]>>16)&0xFF]; - a2 = (uint32_t)aes_sbox[(data[(row+2)%4]>>8)&0xFF]; - a3 = (uint32_t)aes_sbox[(data[(row+3)%4])&0xFF]; + a0 = (uint32_t)(ax_array_read_u8(aes_sbox, (data[row%4]>>24)&0xFF)); + a1 = (uint32_t)(ax_array_read_u8(aes_sbox, (data[(row+1)%4]>>16)&0xFF)); + a2 = (uint32_t)(ax_array_read_u8(aes_sbox, (data[(row+2)%4]>>8)&0xFF)); + a3 = (uint32_t)(ax_array_read_u8(aes_sbox, (data[(row+3)%4])&0xFF)); /* Perform MixColumn iff not last round */ if (curr_rnd < (rounds - 1)) @@ -417,10 +417,10 @@ static void AES_decrypt(const AES_CTX *ctx, uint32_t *data) /* Perform ByteSub and ShiftRow operations together */ for (row = 4; row > 0; row--) { - a0 = aes_isbox[(data[(row+3)%4]>>24)&0xFF]; - a1 = aes_isbox[(data[(row+2)%4]>>16)&0xFF]; - a2 = aes_isbox[(data[(row+1)%4]>>8)&0xFF]; - a3 = aes_isbox[(data[row%4])&0xFF]; + a0 = ax_array_read_u8(aes_isbox, (data[(row+3)%4]>>24)&0xFF); + a1 = ax_array_read_u8(aes_isbox, (data[(row+2)%4]>>16)&0xFF); + a2 = ax_array_read_u8(aes_isbox, (data[(row+1)%4]>>8)&0xFF); + a3 = ax_array_read_u8(aes_isbox, (data[row%4])&0xFF); /* Perform MixColumn iff not last round */ if (curr_rnd<(rounds-1)) diff --git a/crypto/crypto_misc.c b/crypto/crypto_misc.c index 6c7e682d1..c7f086dad 100644 --- a/crypto/crypto_misc.c +++ b/crypto/crypto_misc.c @@ -334,7 +334,7 @@ EXP_FUNC int STDCALL base64_decode(const char *in, int len, g = 3; for (x = y = z = t = 0; x < len; x++) { - if ((c = map[in[x]&0x7F]) == 0xff) + if ((c = ax_array_read_u8(map, in[x]&0x7F)) == 0xff) continue; if (c == 254) /* this is the end... */ diff --git a/crypto/md5.c b/crypto/md5.c index 7f5071300..1a8786f47 100644 --- a/crypto/md5.c +++ b/crypto/md5.c @@ -60,7 +60,7 @@ static void MD5Transform(uint32_t state[4], const uint8_t block[64]); static void Encode(uint8_t *output, uint32_t *input, uint32_t len); static void Decode(uint32_t *output, const uint8_t *input, uint32_t len); -static const uint8_t PADDING[64] = +static const uint8_t PADDING[64] PROGMEM = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -158,7 +158,10 @@ EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *ctx) { uint8_t bits[8]; uint32_t x, padLen; - +#ifdef WITH_PGM_READ_HELPER + uint8_t PADDING_stack[64]; + memcpy(PADDING_stack, PADDING, 64); +#endif /* Save number of bits */ Encode(bits, ctx->count, 8); @@ -166,7 +169,11 @@ EXP_FUNC void STDCALL MD5_Final(uint8_t *digest, MD5_CTX *ctx) */ x = (uint32_t)((ctx->count[0] >> 3) & 0x3f); padLen = (x < 56) ? (56 - x) : (120 - x); +#ifdef WITH_PGM_READ_HELPER + MD5_Update(ctx, PADDING_stack, padLen); +#else MD5_Update(ctx, PADDING, padLen); +#endif /* Append length (before padding) */ MD5_Update(ctx, bits, 8); diff --git a/crypto/sha256.c b/crypto/sha256.c index 50f5f8cef..ba1ac95fe 100644 --- a/crypto/sha256.c +++ b/crypto/sha256.c @@ -48,7 +48,7 @@ (b)[(i) + 3] = (uint8_t) ((n) ); \ } -static const uint8_t sha256_padding[64] = +static const uint8_t sha256_padding[64] PROGMEM = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -249,6 +249,10 @@ void SHA256_Final(uint8_t *digest, SHA256_CTX *ctx) uint32_t last, padn; uint32_t high, low; uint8_t msglen[8]; +#ifdef WITH_PGM_READ_HELPER + uint8_t sha256_padding_ram[64]; + memcpy(sha256_padding_ram, sha256_padding, 64); +#endif high = (ctx->total[0] >> 29) | (ctx->total[1] << 3); @@ -259,8 +263,11 @@ void SHA256_Final(uint8_t *digest, SHA256_CTX *ctx) last = ctx->total[0] & 0x3F; padn = (last < 56) ? (56 - last) : (120 - last); - +#ifdef WITH_PGM_READ_HELPER + SHA256_Update(ctx, sha256_padding_ram, padn); +#else SHA256_Update(ctx, sha256_padding, padn); +#endif SHA256_Update(ctx, msglen, 8); PUT_UINT32(ctx->state[0], digest, 0); diff --git a/ssl/config.h b/ssl/config.h index 8b90bb09c..873143070 100644 --- a/ssl/config.h +++ b/ssl/config.h @@ -45,7 +45,7 @@ #define CONFIG_SSL_HAS_PEM 1 #undef CONFIG_SSL_USE_PKCS12 #define CONFIG_SSL_EXPIRY_TIME 24 -#define CONFIG_X509_MAX_CA_CERTS 150 +#define CONFIG_X509_MAX_CA_CERTS 10 #define CONFIG_SSL_MAX_CERTS 1 #undef CONFIG_SSL_CTX_MUTEXING #undef CONFIG_USE_DEV_URANDOM diff --git a/ssl/os_port.h b/ssl/os_port.h index e672f102c..07377966d 100644 --- a/ssl/os_port.h +++ b/ssl/os_port.h @@ -98,6 +98,31 @@ extern "C" { void ax_wdt_feed(); +#ifndef PROGMEM +#define PROGMEM __attribute__((aligned(4))) __attribute__((section(".irom.text"))) +#endif + +#ifndef WITH_PGM_READ_HELPER +#define ax_array_read_u8(x, y) x[y] +#else + +static inline uint8_t pgm_read_byte(const void* addr) { + register uint32_t res; + __asm__("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ + "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ + "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ + "slli %0, %0, 3\n" /* Multiply offset by 8, yielding an offset in bits */ + "ssr %0\n" /* Prepare to shift by offset (in bits) */ + "srl %0, %1\n" /* Shift right; now the requested byte is the first one */ + :"=r"(res), "=r"(addr) + :"1"(addr) + :); + return (uint8_t) res; /* This masks the lower byte from the returned word */ +} + +#define ax_array_read_u8(x, y) pgm_read_byte((x)+(y)) +#endif //WITH_PGM_READ_HELPER + #elif defined(WIN32) /* Windows CE stuff */ diff --git a/ssl/ssl.h b/ssl/ssl.h index e2b220dd7..09d205a8d 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -233,6 +233,20 @@ EXP_FUNC void STDCALL ssl_ctx_free(SSL_CTX *ssl_ctx); */ EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new(); +/** + * @brief Set the host name for SNI extension + * @param ssl_ext pointer returned by ssl_ext_new + * @param host_name pointer to a zero-terminated string containing host name + */ +EXP_FUNC void STDCALL ssl_ext_set_host_name(SSL_EXTENSIONS * ext, const char* host_name); + +/** + * @brief Set the maximum fragment size for the fragment size negotiation extension + * @param ssl_ext pointer returned by ssl_ext_new + * @param fragment_size fragment size, allowed values: 2^9, 2^10 ... 2^14 + */ +EXP_FUNC void STDCALL ssl_ext_set_max_fragment_size(SSL_EXTENSIONS * ext, unsigned fragment_size); + /** * @brief Frees SSL extensions structure * diff --git a/ssl/tls1.c b/ssl/tls1.c index 4066d4922..7294278ad 100644 --- a/ssl/tls1.c +++ b/ssl/tls1.c @@ -140,7 +140,7 @@ void DISPLAY_BYTES(SSL *ssl, const char *format, #endif /** - * Allocates new SSL extensions structure and returns pointer to it + * Allocate new SSL extensions structure and return pointer to it * */ EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new() @@ -153,7 +153,7 @@ EXP_FUNC SSL_EXTENSIONS * STDCALL ssl_ext_new() } /** - * Allocates new SSL extensions structure and returns pointer to it + * Free SSL extensions structure * */ EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext) @@ -168,6 +168,23 @@ EXP_FUNC void STDCALL ssl_ext_free(SSL_EXTENSIONS *ssl_ext) free(ssl_ext); } +EXP_FUNC void STDCALL ssl_ext_set_host_name(SSL_EXTENSIONS * ext, const char* host_name) +{ + free(ext->host_name); + ext->host_name = NULL; + if (host_name) { + ext->host_name = strdup(host_name); + } +} + +/** + * Set the maximum fragment size for the fragment size negotiation extension + */ +EXP_FUNC void STDCALL ssl_ext_set_max_fragment_size(SSL_EXTENSIONS * ext, unsigned fragment_size) +{ + ext->max_fragment_size = fragment_size; +} + /** * Establish a new client/server context. */ @@ -2426,10 +2443,6 @@ EXP_FUNC void STDCALL ssl_display_error(int error_code) printf("\n"); } -/** - * Debugging routine to display alerts. - */ - /** * Debugging routine to display alerts. */