mirror of
https://github.com/esp8266/Arduino.git
synced 2025-07-27 18:02:17 +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:
committed by
Develo
parent
41de43a263
commit
2f4380777e
@ -27,6 +27,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <Arduino.h>
|
||||
#include <StackThunk.h>
|
||||
#include "BearSSLHelpers.h"
|
||||
|
||||
namespace brssl {
|
||||
@ -825,5 +826,14 @@ bool X509List::append(const uint8_t *derCert, size_t derLen) {
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
// Second stack thunked helpers
|
||||
make_stack_thunk(br_ssl_engine_recvapp_ack);
|
||||
make_stack_thunk(br_ssl_engine_recvapp_buf);
|
||||
make_stack_thunk(br_ssl_engine_recvrec_ack);
|
||||
make_stack_thunk(br_ssl_engine_recvrec_buf);
|
||||
make_stack_thunk(br_ssl_engine_sendapp_ack);
|
||||
make_stack_thunk(br_ssl_engine_sendapp_buf);
|
||||
make_stack_thunk(br_ssl_engine_sendrec_ack);
|
||||
make_stack_thunk(br_ssl_engine_sendrec_buf);
|
||||
|
||||
};
|
@ -136,6 +136,18 @@ class Session {
|
||||
br_ssl_session_parameters _session;
|
||||
};
|
||||
|
||||
// Stack thunked versions of calls
|
||||
extern "C" {
|
||||
extern unsigned char *thunk_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len);
|
||||
extern void thunk_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len);
|
||||
extern unsigned char *thunk_br_ssl_engine_recvrec_buf( const br_ssl_engine_context *cc, size_t *len);
|
||||
extern void thunk_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len);
|
||||
extern unsigned char *thunk_br_ssl_engine_sendapp_buf( const br_ssl_engine_context *cc, size_t *len);
|
||||
extern void thunk_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len);
|
||||
extern unsigned char *thunk_br_ssl_engine_sendrec_buf( const br_ssl_engine_context *cc, size_t *len);
|
||||
extern void thunk_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
|
@ -227,13 +227,6 @@ class WiFiClientSecure : public WiFiClient {
|
||||
|
||||
// AXTLS compatible mode needs to delete the stored certs and keys on destruction
|
||||
bool _deleteChainKeyTA;
|
||||
|
||||
private:
|
||||
// Single memory buffer used for BearSSL auxilliary stack, insead of growing main Arduino stack for all apps
|
||||
static std::shared_ptr<uint8_t> _bearssl_stack;
|
||||
void _ensureStackAvailable(); // Allocate the stack if necessary
|
||||
// The local copy, only used to enable a reference count
|
||||
std::shared_ptr<uint8_t> _local_bearssl_stack;
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -26,6 +26,7 @@ extern "C" {
|
||||
#include "ets_sys.h"
|
||||
}
|
||||
|
||||
#include <StackThunk.h>
|
||||
#include "debug.h"
|
||||
#include "ESP8266WiFi.h"
|
||||
#include "WiFiClient.h"
|
||||
@ -40,14 +41,17 @@ namespace BearSSL {
|
||||
|
||||
// Only need to call the standard server constructor
|
||||
WiFiServerSecure::WiFiServerSecure(IPAddress addr, uint16_t port) : WiFiServer(addr, port) {
|
||||
stack_thunk_add_ref();
|
||||
}
|
||||
|
||||
// Only need to call the standard server constructor
|
||||
WiFiServerSecure::WiFiServerSecure(uint16_t port) : WiFiServer(port) {
|
||||
stack_thunk_add_ref();
|
||||
}
|
||||
|
||||
// Destructor only checks if we need to delete compatibilty cert/key
|
||||
WiFiServerSecure::~WiFiServerSecure() {
|
||||
stack_thunk_del_ref();
|
||||
if (_deleteChainAndKey) {
|
||||
delete _chain;
|
||||
delete _sk;
|
||||
|
Reference in New Issue
Block a user