-
Notifications
You must be signed in to change notification settings - Fork 2.6k
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
Huge certificate parsing speed regression between mbedtls 2.16.9 and 2.16.10 (constant time base64). #4814
Comments
The base64 module doesn't know whether it's working on sensitive data or not. So it always uses a constant-time method. I see four possibilities.
The original base64 implementation in Mbed TLS was table-based. To make it constant-time, we went the conceptually simple route of replacing table lookups by constant-time table lookups. This is fairly slow since it means 128 table lookups when decoding. The table is likely to be in cache, but even so that turns out to make for a significant slowdown. A while ago I started working on a constant-time base64 implementation that used a different approach, based on value ranges. I've completed my work (as far as coding is concerned, some bits of documentation and maybe code polish are missing), and I also wrote a dedicated benchmark program. This is currently based on an older version of Mbed TLS because that's what my patch was for. If this approach is considered acceptable, I'll port the patch to current versions of Mbed TLS. https://github.com/gilles-peskine-arm/mbedtls/tree/base64-no-table-2.16.9 Some timings for
So there's still a significant slowdown, but it's an order of magnitude better than the current version. |
I think your patch looks very promising, @gilles-peskine-arm! @Faless would the new performance be acceptable? |
@gilles-peskine-arm that's some really great work! I've run some in-engine tests, here are the results (Core i7-7700K, Ubuntu 20.04): Debug
Optimized (
I believe some of the difference is due to the fact that your test program reads from file, while in Godot we read directly from memory (packed in a compressed array by the build system) so my timings do not include file system I/O. This looks much better. I understand having a dedicated code path for unsafe bas64 would be complex to properly maintain, and I think this is quite acceptable performance for us @mpg . Many thanks for your work @gilles-peskine-arm ! |
Pull request for 2.16: #4819. Please note that this has not been reviewed yet. It passes the unit tests but no one other than me has checked that the code is constant time. Performance is slightly better than yesterday's patch because I noticed a possible simplification. It's still way above non-constant time code, but I think the difference is reasonable now. |
I've tested the current PR. In debug mode it's twice as fast, optimized builds saw less gain, but still pretty noticeable: Debug
Optimized (
|
mbedtls_x509_crt_parse_file() is slow. This affected startup time by a lot. See Mbed-TLS/mbedtls#4814
Summary
We recently started noticing huge performance regression in Godot Engine TLS certificates parsing code.
System information
Mbed TLS version (number or commit id): v2.16.11 (since 2.16.10)
Operating system and version: Linux (Ubuntu 20.04)/Any.
Steps to reproduce
The
mbedtls_x509_crt_parse
became much slower between versionv2.16.9
andv2.16.10
.It seems form our flamegraph (also attached below with highlight) that this is due to the constant flow table access introduced in: 738d231 .
I understand this was introduced to fix a potential side-channel attack on PEM key decoding:
The commit though, does that for all base64 decoding, which means this also applies to certificate decoding. I don't have the full flamegraph for the 2.16.9 release (I can provide that if you wish), but from raw printing I've seen a 2 order of magnitudes increase in the time to parse our CA list (from ~3 ms to ~500 ms).
I am not sure if certificate parsing needs to be protected against this side-channels attack, but this is having quite an impact on our editor startup time so I felt it was worth reporting.
The text was updated successfully, but these errors were encountered: