Skip to content

Enhancement - Allow linking in smaller set of ciphers on BearSSL to save code space #6005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
earlephilhower opened this issue Apr 22, 2019 · 7 comments · Fixed by #6006 or #6157
Closed

Comments

@earlephilhower
Copy link
Collaborator

This would be, unfortunately, yet another Arduino menu option where you would be able to define specific cipher groups (say, only RSA or only EC or only ChaCha20) would be available for SSL negotiation.

Make sure there are no references to the unused codes in question, and the linker will leave out large swaths of BearSSL code.

Useful for flash constrained people and folks trying to do OTA in 1MB devices.

@earlephilhower
Copy link
Collaborator Author

Did some quick testing and we can drop ~45KB of code by only supporting the subset that AXTLS used to support which are still generally supported by servers in the wild.

    BR_TLS_RSA_WITH_AES_128_CBC_SHA256,
    BR_TLS_RSA_WITH_AES_256_CBC_SHA256,
    BR_TLS_RSA_WITH_AES_128_CBC_SHA,
    BR_TLS_RSA_WITH_AES_256_CBC_SHA,

earlephilhower added a commit to earlephilhower/Arduino that referenced this issue Apr 22, 2019
Adds a menu option and define to limit BearSSL to older RSA connection
options.  This saves ~45K program memory and can speed up connections
since EC, while more secure, is significantly slower on the chip.
The supported ciphers are identical to the ones that axTLS supported.

Fixes esp8266#6005
earlephilhower added a commit to earlephilhower/Arduino that referenced this issue Apr 25, 2019
* New menu option to minimize BSSL ROM with only RSA

Adds a menu option and define to limit BearSSL to older RSA connection
options.  This saves ~45K program memory and can speed up connections
since EC, while more secure, is significantly slower on the chip.
The supported ciphers are identical to the ones that axTLS supported.

Fixes esp8266#6005

* Add default SSLFLAGS(blank) to platform.txt

* Fix unused variable warning

* Add clarifying comment to menu items
@sislakd
Copy link
Contributor

sislakd commented May 9, 2019

It would be good to have there option to use only BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 which is forward secure, symmetric encryption/decryption is faster than AES on ESP8266 and is supported by servers long time.

At some moment I was heap & stack constrained. Thus I've performed detailed investigation and found some places which can help you save heap and stack space:

  • drop X509 context after successful server verification (a.k.a null _x509_minimal, _x509_insecure and _x509_knownkey); (saves heap)
  • reduce BSSL stack in StackThunk for selected cipher suites, e.g. BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 works well with stack 4300. For ciphers used by AxTLS (those 4) it requires even less stack; (saves heap)
  • move constants from ECDHE KEX part of BSSL from RAM to FLASH and update few places to use pgmspace code to access constants; speed effect is only within KEX part and slow down is minimal even using default CPU & FLASH freq; (saves stack)

When I've tested some unstable SSL implementation at remote end, I found that WiFiClientSecureBearSSL is reporting that it is connected even BSSL is already in BR_SSL_CLOSED state (in my case it was caused by invalid MAC after some time sent from the remote peer to ESP8266). Change of condition in WiFiClientSecure::connected() to include test of BSSL state help to fail quickly and application can reconnect without implementing own response timeouts. Specifically, I've added (br_ssl_engine_current_state(_eng) != BR_SSL_CLOSED) into condition.

@earlephilhower
Copy link
Collaborator Author

Those are great ideas! Did you want to try a PR on them?

W/BSSL stack size, it'd really be best to key that off of the compiled-in ciphers and not runtime determined, of course, as you don't want to allocate/reallocate 5K chunks w/only 40KB free heap and no MMU. But It can definitely be a function of the #define. Now that there's an infrastructure and menus it's relatively straightforward.

The original BSSL was ported before the non 32b PROGMEM handler was included in the SDK, so I couldn't easily swap it out w/o massively changing (slowing) the EC code. Today, that's a great idea to move them to flash.

The last bit looks like a bug on my part. ::connected() with SSL is an odd character...

@earlephilhower earlephilhower reopened this May 9, 2019
@earlephilhower
Copy link
Collaborator Author

Reopening since there are some more good ideas here for 2.6.0...

@sislakd
Copy link
Contributor

sislakd commented May 10, 2019

Attaching PR for the first item.

@earlephilhower
Copy link
Collaborator Author

Reopening since there are some more things we can do here (EC key stuff, heap sizing)

earlephilhower added a commit to earlephilhower/Arduino that referenced this issue May 28, 2019
Move additional constants to flash and use _P/pgm_read routines to
access them.  Minimal runtime impact, but remove variables from RODATA
and gives addition 484 bytes of heap to SSL applications.

Fixes esp8266#6005
@earlephilhower
Copy link
Collaborator Author

@sislakd , can you check the BearSSL repo and see if you have anything to add for saving heap? The EC P/N constants I can't move without massive hacking, but I've got everything else out of RODATA/heap and freed ~.5KB.

d-a-v pushed a commit that referenced this issue May 28, 2019
Move additional constants to flash and use _P/pgm_read routines to
access them.  Minimal runtime impact, but remove variables from RODATA
and gives addition 484 bytes of heap to SSL applications.

Fixes #6005
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment