Skip to content

Commit ff9cbef

Browse files
Working code with second stack thunking
1 parent 416660c commit ff9cbef

File tree

5 files changed

+171
-9
lines changed

5 files changed

+171
-9
lines changed

cores/esp8266/cont.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#include <stdbool.h>
2525

2626
#ifndef CONT_STACKSIZE
27-
#define CONT_STACKSIZE (4096+4500)
27+
#define CONT_STACKSIZE 4096
2828
#endif
2929

3030
#ifdef __cplusplus
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
esp8266_thunks.S - Allow use second stack for BearSSL calls
3+
4+
BearSSL uses a significant amount of stack space, much larger than
5+
the default Arduino core stack. These routines handle swapping
6+
between a secondary, user-allocated stack on the heap and the real
7+
stack.
8+
9+
Copyright (c) 2017 Earle F. Philhower, III. All rights reserved.
10+
11+
This library is free software; you can redistribute it and/or
12+
modify it under the terms of the GNU Lesser General Public
13+
License as published by the Free Software Foundation; either
14+
version 2.1 of the License, or (at your option) any later version.
15+
16+
This library is distributed in the hope that it will be useful,
17+
but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19+
Lesser General Public License for more details.
20+
21+
You should have received a copy of the GNU Lesser General Public
22+
License along with this library; if not, write to the Free Software
23+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24+
Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
25+
*/
26+
27+
#ifdef ESP8266
28+
29+
/* We need to keep track of the end of the thunking stack and the */
30+
/* original stack pointer (A1). Keep them local here. */
31+
.data
32+
.align 4
33+
_stackEnd: .word 0x00000000
34+
_saveStack: .word 0x00000000
35+
36+
37+
38+
/* void SetThunkStackEnd(unsigned int *end);
39+
*
40+
* Stores the address of the user-allocated thunking stack (be sure to pass
41+
* in the *end* of the stack (highest value) since stacks move down on this
42+
* architecture.
43+
*/
44+
.text
45+
.global SetThunkStackEnd
46+
.type SetThunkStackEnd, @function
47+
.align 4
48+
SetThunkStackEnd:
49+
movi a15, _stackEnd
50+
s32i a2, a15, 0
51+
ret
52+
.size SetThunkStackEnd, . - SetThunkStackEnd
53+
54+
55+
/*
56+
* Thunk code generator macro. Only works for functions whose parameters
57+
* are passed in registers (up to 6 params).
58+
*/
59+
60+
.macro thunk fcnName
61+
.text
62+
.global thunk_\fcnName
63+
.type thunk_\fcnName, @function
64+
.align 4
65+
thunk_\fcnName:
66+
addi a1, a1, -16 /* Allocate space for saved registers on stack */
67+
68+
s32i a0, a1, 12 /* Store A0, trounced by calls */
69+
s32i a15, a1, 8 /* Store A15 (our temporary one) */
70+
71+
movi a15, _saveStack /* Store A1(SP) in temp space */
72+
s32i a1, a15, 0
73+
74+
movi a15, _stackEnd /* Load A1(SP) with thunk stack */
75+
l32i.n a1, a15, 0
76+
77+
call0 \fcnName /* Do the call */
78+
79+
movi a15, _saveStack /* Restore A1(SP) */
80+
l32i.n a1, a15, 0
81+
82+
l32i.n a15, a1, 8 /* Restore the saved registers */
83+
l32i.n a0, a1, 12
84+
85+
addi a1, a1, 16 /* Free up stack and return to caller */
86+
ret
87+
.size thunk_\fcnName, . - thunk_\fcnName
88+
.endm
89+
90+
/* Actual thunks */
91+
92+
/* Only a few stack-hungry calls need to be thunked */
93+
thunk br_ssl_engine_recvapp_ack
94+
thunk br_ssl_engine_recvapp_buf
95+
thunk br_ssl_engine_recvrec_ack
96+
thunk br_ssl_engine_recvrec_buf
97+
thunk br_ssl_engine_sendapp_ack
98+
thunk br_ssl_engine_sendapp_buf
99+
thunk br_ssl_engine_sendrec_ack
100+
thunk br_ssl_engine_sendrec_buf
101+
102+
#endif
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
esp8266_thunks.h - Allow use second stack for BearSSL calls
3+
4+
BearSSL uses a significant amount of stack space, much larger than
5+
the default Arduino core stack. These routines handle swapping
6+
between a secondary, user-allocated stack on the heap and the real
7+
stack.
8+
9+
Copyright (c) 2017 Earle F. Philhower, III. All rights reserved.
10+
11+
This library is free software; you can redistribute it and/or
12+
modify it under the terms of the GNU Lesser General Public
13+
License as published by the Free Software Foundation; either
14+
version 2.1 of the License, or (at your option) any later version.
15+
16+
This library is distributed in the hope that it will be useful,
17+
but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19+
Lesser General Public License for more details.
20+
21+
You should have received a copy of the GNU Lesser General Public
22+
License along with this library; if not, write to the Free Software
23+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24+
Modified 8 May 2015 by Hristo Gochkov (proper post and file upload handling)
25+
*/
26+
27+
#ifndef _BearSSLThunks_H
28+
#define _BearSSLThunks_H
29+
30+
extern "C" {
31+
32+
#include <bearssl/bearssl.h>
33+
34+
extern void SetThunkStackEnd(unsigned int *end);
35+
36+
extern unsigned char *thunk_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len);
37+
extern void thunk_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len);
38+
extern unsigned char *thunk_br_ssl_engine_recvrec_buf( const br_ssl_engine_context *cc, size_t *len);
39+
extern void thunk_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len);
40+
extern unsigned char *thunk_br_ssl_engine_sendapp_buf( const br_ssl_engine_context *cc, size_t *len);
41+
extern void thunk_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len);
42+
extern unsigned char *thunk_br_ssl_engine_sendrec_buf( const br_ssl_engine_context *cc, size_t *len);
43+
extern void thunk_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len);
44+
45+
}
46+
47+
#endif

libraries/ESP8266WiFi/src/WiFiClientSecureBearSSL.cpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ extern "C" {
3434
#include "ESP8266WiFi.h"
3535
#include "WiFiClient.h"
3636
#include "WiFiClientSecureBearSSL.h"
37+
#include "BearSSLThunks.h"
3738
#include "lwip/opt.h"
3839
#include "lwip/ip.h"
3940
#include "lwip/tcp.h"
@@ -43,6 +44,16 @@ extern "C" {
4344
#include "c_types.h"
4445
#include "coredecls.h"
4546

47+
#define br_ssl_engine_recvapp_ack thunk_br_ssl_engine_recvapp_ack
48+
#define br_ssl_engine_recvapp_buf thunk_br_ssl_engine_recvapp_buf
49+
#define br_ssl_engine_recvrec_ack thunk_br_ssl_engine_recvrec_ack
50+
#define br_ssl_engine_recvrec_buf thunk_br_ssl_engine_recvrec_buf
51+
#define br_ssl_engine_sendapp_ack thunk_br_ssl_engine_sendapp_ack
52+
#define br_ssl_engine_sendapp_buf thunk_br_ssl_engine_sendapp_buf
53+
#define br_ssl_engine_sendrec_ack thunk_br_ssl_engine_sendrec_ack
54+
#define br_ssl_engine_sendrec_buf thunk_br_ssl_engine_sendrec_buf
55+
56+
4657
namespace BearSSL {
4758

4859
// BearSSL needs a very large stack, larger than the entire ESP8266 Arduino
@@ -91,12 +102,14 @@ WiFiClientSecure::WiFiClientSecure() : WiFiClient() {
91102
_clear();
92103
_clearAuthenticationSettings();
93104
_certStore = nullptr; // Don't want to remove cert store on a clear, should be long lived
94-
// if (!_bearssl_stack) {
95-
// const int stacksize = 4500; // Empirically determined stack for EC and RSA connections
96-
// _bearssl_stack = std::shared_ptr<uint8_t>(new uint8_t[stacksize], std::default_delete<uint8_t[]>());
97-
// br_esp8266_stack_proxy_init(_bearssl_stack.get(), stacksize);
98-
// }
99-
// _local_bearssl_stack = _bearssl_stack;
105+
if (!_bearssl_stack) {
106+
const int stacksize = 4500; // Empirically determined stack for EC and RSA connections
107+
_bearssl_stack = std::shared_ptr<uint8_t>(new uint8_t[stacksize], std::default_delete<uint8_t[]>());
108+
unsigned int *endOfStack = (unsigned int *)_bearssl_stack.get();
109+
endOfStack += (stacksize/4) - 1;
110+
SetThunkStackEnd(endOfStack);
111+
}
112+
_local_bearssl_stack = _bearssl_stack;
100113
}
101114

102115
WiFiClientSecure::~WiFiClientSecure() {
@@ -106,7 +119,7 @@ WiFiClientSecure::~WiFiClientSecure() {
106119
}
107120
free(_cipher_list);
108121
_freeSSL();
109-
// _local_bearssl_stack = nullptr; // Potentially delete it if we're the last SSL object
122+
_local_bearssl_stack = nullptr; // Potentially delete it if we're the last SSL object
110123
if (_deleteChainKeyTA) {
111124
delete _ta;
112125
delete _chain;

libraries/ESP8266WiFi/src/include/ClientContext.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,10 +327,10 @@ class ClientContext
327327
loop = max_wait_ms;
328328
}
329329

330+
delay(1);
330331
if (state() != ESTABLISHED || sndbuf == TCP_SND_BUF || --loop <= 0)
331332
break;
332333

333-
delay(1);
334334
}
335335

336336
#ifdef DEBUGV

0 commit comments

Comments
 (0)