Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

WiFiServerSecure: Cache SSL sessions#7774

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
earlephilhower merged 9 commits intoesp8266:masterfromZakCodes:server-ssl-sessions
Dec 22, 2020

Conversation

@ZakCodes
Copy link
Contributor

@ZakCodesZakCodes commentedDec 17, 2020
edited
Loading

WiFiClientSecure::setSession allows users to use a feature in BearSSL to cache the SSL session to a server.

BearSSL also allows caching SSL session on the server side, therefore I've created the methodWiFiServerSecure::setCache to allow the user to setup a cache allowing BearSSL to resume the SSL sessions of client and greatly shorten the length of TLS handshakes.

Here are the steps that I have followed when implementing this feature:

  • Implement the feature theESP8266WiFi library
  • Add the new classes and methods to theESP8266WiFi librarykeywords.txt file
  • Use the feature in an example in theESP8266WiFi library (I've chosen theBearSSL_Server example)
  • Use the feature in an example inESP8266WebServer library (I've chosen theHelloServerBearSSL example)
  • Document the feature in the rst docs

If you want to test this feature, I encourage you to use these examples and to enable and disable the cache to see the performance improvements. In order to reset the server's cache, you simply have to reset the microcontroller.

Testing the examples

Here's a ruby script that I've written to test the performance improvements that this PR is bringing. It does 100 requests using a new SSL session each time and 100 more using the same session.

#!/bin/env rubyrequire'net/http'require'benchmark'DOMAIN="<your controller's IP>"TIMES=100TEST_URI=URI("https://#{DOMAIN}/")defstart_session()http=Net::HTTP.new(TEST_URI.host,TEST_URI.port)http.use_ssl=true# Allow self signed certificateshttp.verify_mode=OpenSSL::SSL::VERIFY_NONEreturnhttpendrequest=Net::HTTP::Get.new(TEST_URI)request["Connection"]="close"Benchmark.bm(20)do |bm|http=start_session()bm.report("don't reuse session:"){TIMES.timesdo |_|http=start_session()http.request(request)end}# The cached session of the last request is used.# Otherwise this would massively slow down the first request# when we're trying to test the improvement of cached sessions.bm.report("reuse session:"){TIMES.timesdo |_|response=http.request(request)# Reuse the cached session.end}end

Results

I've used this script to test theBearSSL_Server andHelloServerBearSSL examples before, after this PR without the cache activated and after this PR with the cache activated. ForBearSSL_Server, I did the test once with the RSA key and another time with the EC key.

BearSSL_Server with the RSA key

Before the PR
                           user     system      total        realdon't reuse session:   0.288973   0.082934   0.371907 (183.731719)reuse session:         0.285080   0.091825   0.376905 (184.243461)
After the PR without caching
                           user     system      total        realdon't reuse session:   0.367846   0.071787   0.439633 (183.834841)reuse session:         0.340344   0.089750   0.430094 (184.414041)
After the PR with caching
                           user     system      total        realdon't reuse session:   0.312145   0.102594   0.414739 (184.679486)reuse session:         0.204378   0.063052   0.267430 (  6.986146)
Summary
Don't reuse the session (s)Reuse the session (s)Improvement
Before the PR183.731719184.2434610.997
After the PR (without caching)183.834841184.4140410.997
After the PR (with caching)184.6794866.98614626.435

The improvement ratio is the time ofDon't reuse the session over the time ofReuse the session.

BearSSL_Server with the EC key

Before the PR
                           user     system      total        realdon't reuse session:   0.302631   0.104204   0.406835 ( 35.997831)reuse session:         0.305480   0.119427   0.424907 ( 36.882044)
After the PR without caching
08:54:58 PM                           user     system      total        realdon't reuse session:   0.339462   0.088985   0.428447 ( 36.511242)reuse session:         0.320082   0.097038   0.417120 ( 37.105757)
After the PR with caching
                           user     system      total        realdon't reuse session:   0.338105   0.107970   0.446075 ( 36.216895)reuse session:         0.224127   0.066317   0.290444 (  5.896962)
Summary
Don't reuse the session (s)Reuse the session (s)Improvement
Before the PR35.99783136.8820440.976
After the PR (without caching)36.51124237.1057570.984
After the PR (with caching)36.2168955.8969626.142

The improvement ratio is the time ofDon't reuse the session over the time ofReuse the session.

HelloServerBearSSL

Before the PR

                           user     system      total        realdon't reuse session:   0.304455   0.081010   0.385465 (184.723887)reuse session:         0.321123   0.100000   0.421123 (184.567364)

After the PR without caching

                           user     system      total        realdon't reuse session:   0.344634   0.115067   0.459701 (187.112183)reuse session:         0.371673   0.073724   0.445397 (185.084550)

After the PR with caching

                           user     system      total        realdon't reuse session:   0.345185   0.102189   0.447374 (185.611363)reuse session:         0.221588   0.078481   0.300069 (  7.925369)
Summary
Don't reuse the session (s)Reuse the session (s)Improvement
Before the PR184.723887184.5673641.001
After the PR (without caching)187.112183185.0845501.011
After the PR (with caching)185.6113637.92536923.4199

The improvement ratio is the time ofDon't reuse the session over the time ofReuse the session.

Analysis

Those numbers show that this PR makes the HTTPS requests about 25x faster with an RSA key and 6x with an EC key when caching is enabled. When caching isn't enabled, this PR doesn't seem to negatively affect performance at all.

We can see thatBearSSL_Server is faster thanHelloServerBearSSL and its improvement is greater, because this PR only improves the TLS handshake, so the longer the server takes to parse the request and create a response, the less improvement there is andHelloServerBearSSL implements a web server which is slower thanBearSSL_Server that answers all requests with the same response without parsing them.

It is to be noted that, in the script that reuses the session, the time of the first request of the session isn't counted because this PR doesn't improve it.

Testing the TLS handshake improvement

The previous test was testing the speed improvement for the full HTTP request, but this PR should only improves the TLS handshake.
In order to see it I've tested theBearSSL_Server with an RSA and an EC key usingFirefox's network timing analyzer.
This test is a little less rigourous, because I didn't do it 100 times like the others, but it allows us to see the improvement for each part of the request.

RSA key

Before the PR

rsa-before

After the PR without caching

rsa-after-nc

After the PR with caching

First request:
rsa-after-wc-1

All subsequent requests:
rsa-after-wc-2

Summary

ConnectionTLS SetupWaitingTotal without connection
Measure (ms)ImprovementMeasure (ms)ImprovementMeasure (ms)ImprovementMeasure (ms)Improvement
Before the PR611730196118261
After the PR, without caching480.12517301921.04318221.002
After the PR, with caching, not cached520.11517400.994901.06718300.998
After the PR, with caching, cached323944.359156.45433.815

The improvement is the measure before the PR over the current measure.

EC key

Before the PR

ec-before

After the PR without caching

ec-after-nc

After the PR with caching

First request:
ec-after-wc-1

All subsequent requests:
ec-after-wc-2

Summary

ConnectionTLS SetupWaitingTotal without connection
Measure (ms)ImprovementMeasure (ms)ImprovementMeasure (ms)ImprovementMeasure (ms)Improvement
Before the PR28130913813471
After the PR, without caching2143120.99390.9743510.989
After the PR, with caching, not cached410.6833091440.8643530.983
After the PR, with caching, cached39.333843.679132.923973.577

The improvement is the measure before the PR over the current measure.

Analysis

These numbers show the same thing as the previous tests: this PR greatly improves the speed of cached requests and doesn't have any noticeable downside.

However, this test shows clearly shows how much the TLS handshake is a bottleneck without this PR and how much it's improved when the server caches the client's sessions.

Somehow it also slightly improves the waiting time for the server response. I don't think it means that the server decrypts the request faster or processes it faster in any way. I simply think that this is because when resuming cached sessions the client ends the handshake instead of the server. This means that the client can start sending the application data at the same time as it sends the TLS record to end the handshake. This would therefore reduce the time the client has to wait for the server response.

You can see this at page 35 and 36 of the TLS 1.2 standard:

      Client                                               Server      ClientHello                  -------->                                                      ServerHello                                                     Certificate*                                               ServerKeyExchange*                                              CertificateRequest*                                   <--------      ServerHelloDone      Certificate*      ClientKeyExchange      CertificateVerify*      [ChangeCipherSpec]      Finished                     -------->                                               [ChangeCipherSpec]                                   <--------             Finished      Application Data             <------->     Application Data             Figure 1.  Message flow for a full handshake
      Client                                                Server      ClientHello                   -------->                                                       ServerHello                                                [ChangeCipherSpec]                                    <--------             Finished      [ChangeCipherSpec]      Finished                      -------->      Application Data              <------->     Application Data          Figure 2.  Message flow for an abbreviated handshake

Conclusion

This PR doesn't seem to have any negative performance impact, only positive ones. Once enabled by the user, it will increase performance of cached sessions by 20 to 25 times depending the type of encryption used. The slower the encryption is, the more this feature will boost performances. However, users need to be well aware that the TLS client they're using also needs to cache the session in order to experiment this performance boost. This is why it was clearly mentionned in the documentation.

@ZakCodesZakCodes changed the titleServer ssl sessionsWiFiServerSecure: Cache SSL sessionsDec 19, 2020
Copy link
Collaborator

@earlephilhowerearlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thanks, this looks like a great addition! Just a minor API request, please.

Copy link
Collaborator

@earlephilhowerearlephilhower left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Thanks for the update.

LGTM and seems very useful!

@ZakCodes
Copy link
ContributorAuthor

No problems! It's always a pleasure to contribute to this repository

@earlephilhowerearlephilhower merged commit032db6f intoesp8266:masterDec 22, 2020
@ZakCodesZakCodes deleted the server-ssl-sessions branchDecember 22, 2020 13:59
davisonja added a commit to davisonja/Arduino that referenced this pull requestDec 28, 2020
…lash* upstream/master: (72 commits)  Typo error in ESP8266WiFiGeneric.h (esp8266#7797)  lwip2: use pvPortXalloc/vPortFree and "-free -fipa-pta" (esp8266#7793)  Use smarter cache key, cache Arduino IDE (esp8266#7791)  Update to SdFat 2.0.2, speed SD access (esp8266#7779)  BREAKING - Upgrade to upstream newlib 4.0.0 release (esp8266#7708)  mock: +hexdump() from debug.cpp (esp8266#7789)  more lwIP physical interfaces (esp8266#6680)  Rationalize File timestamp callback (esp8266#7785)  Update to LittleFS v2.3 (esp8266#7787)  WiFiServerSecure: Cache SSL sessions (esp8266#7774)  platform.txt: instruct GCC to perform more aggressive optimization (esp8266#7770)  LEAmDNS fixes (esp8266#7786)  Move uzlib to master branch (esp8266#7782)  Update to latest uzlib upstream (esp8266#7776)  EspSoftwareSerial bug fix release 6.10.1: preciseDelay() could delay() for extremely long time, if period duration was exceeded on entry. (esp8266#7771)  Fixed OOM double count in umm_realloc. (esp8266#7768)  Added missing check for failure on umm_push_heap calls in Esp.cpp (esp8266#7767)  Fix: cannot build afteresp8266#7060 on Win64 (esp8266#7754)  Add the missing 'rename' method wrapper in SD library. (esp8266#7766)  i2s: adds i2s_rxtxdrive_begin(enableRx, enableTx, driveRxClocks, driveTxClocks) (esp8266#7748)  ...
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@earlephilhowerearlephilhowerearlephilhower approved these changes

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

2 participants

@ZakCodes@earlephilhower

[8]ページ先頭

©2009-2025 Movatter.jp