1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-06-15 00:02:49 +03:00

Move BearSSL from STACK_PROXY to a real, thunked 2nd stack (#5168)

* Update to BearSSL 0.6+ release, add AES_CCM modes

Pull in latest BearSSL head (0.6 + minor additions) release and add AES_CCM
modes to the encryption options.

* Enable the aes_ccm initialization in client/server

* Initial attempt

* Working code with second stack thunking

* Remove #ifdefs in .S file, not needed.

* Clean up thunks and remove separate stack flag

* Fix PIO assembler errors

* Remove #ifdef code changes, ensure same code as PC

Remove "#ifdef ESP8266;...;#else;...;#endif" brackets in BearSSL to
ensure the host-tested code is the same as the ESP8266-run code.

* Move to latest BearSSL w/EC progmem savings

* Merge with master

* Add br_thunk_* calls to do ref counting, painting

Add reference counting br_thunk_add/del_ref() to replace stack handling code
in the class.

Add in stack painting and max usage calculation.

* Add in postmortem stack dump hooks

When a crash occurs while in the second stack, dump the BSSL stack and
then also the stack that it was called from (either cont or sys).

* Update stack dump to match decoder expectations

* Move thunk to code core for linkiage

The thunk code needs to be visible to the core routines, so move it to the
cores/esp8266 directory.  Probably need to refactor the stack setup and the
bearssl portion to avoid dependency on bearssl libs in cores/esp8266

* Add 2nd stack dump utility routine

* Refactor once more, update stack size, add stress

Make stack_thunks generic, remove bearssl include inside of cores/esp8266.

Allocate the stack on a WiFiServerSecure object creation to avoid
fragmentation since we will need to allocate the stack to do any
connected work, anyway.

A stress test is now included which checks the total BearSSL second
stack usage for a variety of TLS handshake and certificate options
from badssl.org.

* Update to latest to-thunks branch

* Add BearSSL device test using stack stress

Run a series of SSL connection and transmission tests that stress
BearSSL and its stack usage to the device tests.

Modify device tests to include a possible SPIFFS generation and
upload when a make_spiffs.py file is present in a test directory.

* Use bearssl/master branch, not /to-thunks branch

Update to use the merged master branch of bearssl.  Should have no code
changes.
This commit is contained in:
Earle F. Philhower, III
2018-11-14 18:29:24 -08:00
committed by Develo
parent 41de43a263
commit 2f4380777e
17 changed files with 562 additions and 40 deletions

View File

@ -34,6 +34,7 @@ extern "C" {
#include "ESP8266WiFi.h"
#include "WiFiClient.h"
#include "WiFiClientSecureBearSSL.h"
#include "StackThunk.h"
#include "lwip/opt.h"
#include "lwip/ip.h"
#include "lwip/tcp.h"
@ -43,15 +44,18 @@ extern "C" {
#include "c_types.h"
#include "coredecls.h"
// The BearSSL thunks in use for now
#define br_ssl_engine_recvapp_ack thunk_br_ssl_engine_recvapp_ack
#define br_ssl_engine_recvapp_buf thunk_br_ssl_engine_recvapp_buf
#define br_ssl_engine_recvrec_ack thunk_br_ssl_engine_recvrec_ack
#define br_ssl_engine_recvrec_buf thunk_br_ssl_engine_recvrec_buf
#define br_ssl_engine_sendapp_ack thunk_br_ssl_engine_sendapp_ack
#define br_ssl_engine_sendapp_buf thunk_br_ssl_engine_sendapp_buf
#define br_ssl_engine_sendrec_ack thunk_br_ssl_engine_sendrec_ack
#define br_ssl_engine_sendrec_buf thunk_br_ssl_engine_sendrec_buf
namespace BearSSL {
// BearSSL needs a very large stack, larger than the entire ESP8266 Arduino
// default one. This shared_pointer is allocated on first use and cleared
// on last cleanup, with only one stack no matter how many SSL objects.
std::shared_ptr<uint8_t> WiFiClientSecure::_bearssl_stack = nullptr;
void WiFiClientSecure::_clear() {
// TLS handshake may take more than the 5 second default timeout
_timeout = 15000;
@ -91,16 +95,7 @@ WiFiClientSecure::WiFiClientSecure() : WiFiClient() {
_clear();
_clearAuthenticationSettings();
_certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived
_ensureStackAvailable();
_local_bearssl_stack = _bearssl_stack;
}
void WiFiClientSecure::_ensureStackAvailable() {
if (!_bearssl_stack) {
const int stacksize = 4500; // Empirically determined stack for EC and RSA connections
_bearssl_stack = std::shared_ptr<uint8_t>(new uint8_t[stacksize], std::default_delete<uint8_t[]>());
br_esp8266_stack_proxy_init(_bearssl_stack.get(), stacksize);
}
stack_thunk_add_ref();
}
WiFiClientSecure::~WiFiClientSecure() {
@ -110,11 +105,8 @@ WiFiClientSecure::~WiFiClientSecure() {
}
free(_cipher_list);
_freeSSL();
_local_bearssl_stack = nullptr;
// If there are no other uses than the initial creation, free the stack
if (_bearssl_stack.use_count() == 1) {
_bearssl_stack = nullptr;
}
// Serial.printf("Max stack usage: %d bytes\n", br_thunk_get_max_usage());
stack_thunk_del_ref();
if (_deleteChainKeyTA) {
delete _ta;
delete _chain;
@ -127,8 +119,7 @@ WiFiClientSecure::WiFiClientSecure(ClientContext* client,
int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta) {
_clear();
_clearAuthenticationSettings();
_ensureStackAvailable();
_local_bearssl_stack = _bearssl_stack;
stack_thunk_add_ref();
_iobuf_in_size = iobuf_in_size;
_iobuf_out_size = iobuf_out_size;
_client = client;
@ -146,8 +137,7 @@ WiFiClientSecure::WiFiClientSecure(ClientContext *client,
int iobuf_in_size, int iobuf_out_size, const X509List *client_CA_ta) {
_clear();
_clearAuthenticationSettings();
_ensureStackAvailable();
_local_bearssl_stack = _bearssl_stack;
stack_thunk_add_ref();
_iobuf_in_size = iobuf_in_size;
_iobuf_out_size = iobuf_out_size;
_client = client;