393 lines
12 KiB
Markdown
393 lines
12 KiB
Markdown
# TLS power measure benchmark
|
|
|
|
Goal: measure the power overhead of adding TLS to a client or a server, on realistic loads.
|
|
|
|
Realistic load implies using a real-world client (such as a web browser on a low-end device) and server (such as a video streaming platform on a typical server).
|
|
|
|
Problem: realistic clients have complex behaviors that go beyond a simple OpenSSL example code, and modern browsers and website won't work without HTTPS.
|
|
|
|
Assumption: most of the load added by the security layers is decoupled from the application (in both web browsers and web servers).
|
|
|
|
```
|
|
Experiments:
|
|
1: (Client) <=[TLS]=> (Proxy 1) <-[plain]-> (Proxy 2) <-[plain]-> (Proxy 3) <=[TLS]=> (Server)
|
|
2: (Client) <=[TLS]=> (Proxy 1) <==[TLS]==> (Proxy 2) <-[plain]-> (Proxy 3) <=[TLS]=> (Server)
|
|
3: (Client) <=[TLS]=> (Proxy 1) <-[plain]-> (Proxy 2) <==[TLS]==> (Proxy 3) <=[TLS]=> (Server)
|
|
^measure^
|
|
```
|
|
|
|
Client and server are identical in all experiments. The only modification made to the client is to add a trusted certificate owned by Proxy 1.
|
|
|
|
Only Proxy 2 must be a dedicated machine. The other parties may be placed on the same machine.
|
|
|
|
Call E1, E2, E3 the energy measured for Proxy 2 in experiments 1, 2, 3.
|
|
|
|
E2-E1 is the energy used to operate the server's half of a TLS connection.
|
|
|
|
E3-E1 is the energy used to operate the client's half of a TLS connection.
|
|
|
|
Client:
|
|
* Web browser trusting a certificate owned by Proxy 1
|
|
|
|
## Things to experiment
|
|
|
|
* Implementations
|
|
* OpenSSL 1.0.2
|
|
* OpenSSL 1.1.1
|
|
* OpenSSL 3.0
|
|
* OpenSSL 3.2
|
|
* OpenSSL 3.3
|
|
* OpenSSL 3.4
|
|
* OpenSSL 3.5
|
|
* OpenSSL 3.6
|
|
* [WolfSSL](https://github.com/wolfSSL/wolfssl)
|
|
* GnuTLS
|
|
* [NSS](https://github.com/nss-dev/nss) (used by Firefox) (?)
|
|
* opencryptoki (?)
|
|
* AWS-LC
|
|
* [BoringSSL](https://github.com/google/boringssl) (Chrome, Android)
|
|
* LibreSSL
|
|
* [SymCrypt](https://github.com/microsoft/SymCrypt) (used by Windows) ([install manually](https://github.com/microsoft/SymCrypt/releases))
|
|
* Versions
|
|
* TLS 1.2
|
|
* TLS 1.3
|
|
* Features
|
|
* TLS
|
|
* Ciphers
|
|
* TLS_AES_128_GCM_SHA256
|
|
* TLS_AES_256_GCM_SHA384
|
|
* TLS_CHACHA20_POLY1305_SHA256
|
|
* TLS_AES_128_CCM_SHA256
|
|
* TLS_AES_128_CCM_8_SHA256
|
|
* Key exchange groups
|
|
* secp256r1
|
|
* secp384r1
|
|
* secp521r1
|
|
* x25519
|
|
* x448
|
|
* ffdhe2048
|
|
* ffdhe3072
|
|
* ffdhe4096
|
|
* ffdhe6144
|
|
* ffdhe8192
|
|
* Signatures
|
|
* rsa_pkcs1_sha256
|
|
* rsa_pkcs1_sha384
|
|
* rsa_pkcs1_sha512
|
|
* ecdsa_secp256r1_sha256
|
|
* ecdsa_secp384r1_sha384
|
|
* ecdsa_secp521r1_sha512
|
|
* rsa_pss_rsae_sha256
|
|
* rsa_pss_rsae_sha384
|
|
* rsa_pss_rsae_sha512
|
|
* ed25519
|
|
* ed448
|
|
* rsa_pss_pss_sha256
|
|
* rsa_pss_pss_sha384
|
|
* rsa_pss_pss_sha512
|
|
* rsa_pkcs1_sha1
|
|
* ecdsa_sha1
|
|
* X.509
|
|
* Signature algorithm
|
|
* RSA2048
|
|
* RSA3072
|
|
* RSA4096
|
|
* EC 256
|
|
* EC 384
|
|
* SCT
|
|
* TODO !!!
|
|
* Usages
|
|
* Video streaming
|
|
* Full-speed download
|
|
* Real-time video call
|
|
* Mostly text browsing
|
|
* With or without ads
|
|
|
|
Most of the implementations can be used through RusTLS.
|
|
|
|
However RusTLS clients won't enable to force TLS1.2 if 1.3 is available.
|
|
|
|
* séparer conso crypto / trafic
|
|
* mesure avec debugger : quelles fonctions consomment
|
|
* mesure mémoire
|
|
* mesure overhead
|
|
|
|
### WolfSSL
|
|
|
|
```bash
|
|
git clone https://github.com/wolfSSL/wolfssl --depth 1
|
|
cd wolfssl
|
|
sh autogen.sh
|
|
./configure --enable-all --enable-all-crypto --disable-shared --prefix=/opt/wolfssl-rs/
|
|
make
|
|
sudo make install
|
|
```
|
|
|
|
## State of the art
|
|
|
|
* https://pub.h-brs.de/frontdoor/deliver/index/docId/4771/file/2019-ESP32-TLS-Power.pdf
|
|
* 2019
|
|
* TLS 1.2, 1.3
|
|
* ESP32
|
|
* WolfSSL
|
|
* https://www.semanticscholar.org/paper/Energy-Consumption-Framework-and-Analysis-of-on-Patterson-Buchanan/706736a29cef777e5dc50ba22b4788b2bfb4c6ef
|
|
* 2025
|
|
* RaspberryPi
|
|
* OpenSSL
|
|
* ML-KEM
|
|
* https://www.semanticscholar.org/paper/Energy-Profiling-and-Comparison-of-TLS-Protocols-Gatram-Reddy/9c061fe57a0008574b85919bc70fc803c6e66f06
|
|
* Energy Profiling and Comparison of TLS Protocols for Embedded Devices: Experimental Study
|
|
* 2024
|
|
* RaspberryPi
|
|
* TLS PQ, TLS KEM, TLS
|
|
* https://www.semanticscholar.org/paper/Energy-Consumption-Evaluation-of-Post-Quantum-TLS-Tasopoulos-Dimopoulos/2ffc6d13349e2fa5f89aaf18e69ce2044ecef4fe
|
|
* 2023
|
|
* STM Nucleo
|
|
* WolfSSL
|
|
* TLS 1.3 PQ
|
|
* https://arxiv.org/pdf/2508.04583v2
|
|
* 2025
|
|
* TLS 1.3
|
|
* Nginx + Python requests
|
|
* https://github.com/MarcT0K/privacy-carbon-experiments
|
|
* https://davidtnaylor.com/CostOfTheS.pdf
|
|
* 2014
|
|
* https://www.researchgate.net/publication/359906722_Performance_Analysis_of_SSLTLS_Crypto_Libraries_Based_on_Operating_Platform
|
|
* 2022
|
|
* throughput & cpu
|
|
* OpenSSL, GnuTLS, Boring, S2n, NSS, Cryptlib
|
|
* https://www.haproxy.com/blog/state-of-ssl-stacks
|
|
* 2025
|
|
* OpenSSL
|
|
* https://ieeexplore.ieee.org/abstract/document/5983970
|
|
* TLS and energy consumption on a mobile device: A measurement study
|
|
* 2011
|
|
* TLS
|
|
* Nokia phone
|
|
* https://dspace.mit.edu/handle/1721.1/111861
|
|
* Energy-efficient protocols and hardware architectures for transport layer security
|
|
* 2017
|
|
* https://dl.acm.org/doi/abs/10.1145/871506.871518
|
|
* Analyzing the energy consumption of security protocols
|
|
* 2003
|
|
* SSL
|
|
* https://ieeexplore.ieee.org/abstract/document/1563998
|
|
* A study of the energy consumption characteristics of cryptographic algorithms and security protocols
|
|
* 2003
|
|
* SSL
|
|
* https://ieeexplore.ieee.org/abstract/document/8598334
|
|
* Energy and Processing Demand Analysis of TLS Protocol in Internet of Things Applications
|
|
* 2016
|
|
* TLS
|
|
* https://dl.acm.org/doi/10.1145/3345768.3355924
|
|
* A Comprehensive Empirical Analysis of TLS Handshake and Record Layer on IoT Platforms
|
|
* 2019
|
|
* IoT, TLS
|
|
* https://hal.science/hal-04197885/document
|
|
* Empreinte carbone de la transmission de données sur le backbone RENATER
|
|
* 2021
|
|
* https://ieeexplore.ieee.org/document/10971851/
|
|
* Optimizing TLS/SSL for IoT Devices: Performance Enhancements and Security Considerations
|
|
* 2024
|
|
* https://ieeexplore.ieee.org/document/10060762/
|
|
* Performance Evaluation of Quantum-Resistant TLS for Consumer IoT Devices
|
|
* 2023
|
|
*
|
|
* Evaluating the Energy Profile of Tasks Managed by Build Automation Tools in Continuous Integration Workflows: The Case of Apache Maven and Gradle
|
|
* 2025
|
|
|
|
## Sources
|
|
|
|
* [RFC8446 (TLS 1.3)](https://datatracker.ietf.org/doc/html/rfc8446)
|
|
|
|
## Reproduce
|
|
|
|
### Record
|
|
|
|
Authorize rpxy and netreplay to bind to ports 80 and 443:
|
|
```bash
|
|
sudo setcap CAP_NET_BIND_SERVICE=+eip netreplay
|
|
```
|
|
|
|
Open Firefox with a dedicated profile: (create the profile using the GUI if it doesn't exist)
|
|
|
|
```bash
|
|
firefox -P tlsbench
|
|
```
|
|
|
|
In settings, disable DNS security.
|
|
|
|
In `about:config`, set:
|
|
* `devtools.chrome.enabled` to `true`
|
|
* `network.dns.forceResolve` to `127.0.0.1`
|
|
|
|
In the `about:config` tab, open the console, execute this script to override DNS for the selected names, and redirect them to localhost:
|
|
|
|
Run the shell commands:
|
|
|
|
```bash
|
|
python exp.py make debug -c
|
|
python exp.py update-certs debug
|
|
```
|
|
|
|
In Firefox, go to security settings, Certificates, import `/dev/shm/exp/certs/prime256v1/ca.crt` and trust it for identifying websites.
|
|
|
|
Stop anything running on ports 80 or 443.
|
|
|
|
Start the record proxy:
|
|
|
|
```bash
|
|
./netreplay records/mynewrecord record
|
|
```
|
|
|
|
Just browse. Any traffic to and from the selected names will be recorded. Terminate netplayer with CTRL+C when finished.
|
|
|
|
### Measure
|
|
|
|
Measure resource cost on a different machine.
|
|
|
|
Add p2 the `/etc/hosts`:
|
|
|
|
```
|
|
192.168.3.14 p2
|
|
```
|
|
|
|
Install things on p2:
|
|
|
|
```bash
|
|
sudo apt install acct dtach
|
|
sudo chmod +s /sbin/sa
|
|
```
|
|
|
|
Run:
|
|
|
|
```bash
|
|
python exp.py make pi -c
|
|
python exp.py send pi
|
|
python exp.py update-certs pi # also do this command on p2
|
|
python exp.py run pi --idle
|
|
```
|
|
|
|
On Debian, update-certs says 0 certs added even if it has actually updated some certs. This step is still needed.
|
|
|
|
### Profile
|
|
|
|
Profile code execution on the local machine.
|
|
|
|
Add the domains the `/etc/hosts`:
|
|
|
|
```
|
|
127.0.0.1 youtube.com.localhost
|
|
127.0.0.1 www.youtube.com.localhost
|
|
127.0.0.1 i.ytimg.com.localhost
|
|
127.0.0.1 fonts.gstatic.com.localhost
|
|
127.0.0.1 www.gstatic.com.localhost
|
|
127.0.0.1 www.google.com.localhost
|
|
127.0.0.1 accounts.google.com.localhost
|
|
127.0.0.1 yt3.ggpht.com.localhost
|
|
127.0.0.1 rr1---sn-gxo5uxg-jqbl.googlevideo.com.localhost
|
|
127.0.0.1 rr2---sn-gxo5uxg-jqbl.googlevideo.com.localhost
|
|
127.0.0.1 rr4---sn-q4fl6nds.googlevideo.com.localhost
|
|
127.0.0.1 fr.wikipedia.org.localhost
|
|
127.0.0.1 upload.wikimedia.org.localhost
|
|
127.0.0.1 apple.com.localhost
|
|
127.0.0.1 www.apple.com.localhost
|
|
192.168.3.1 youtube.com
|
|
192.168.3.1 www.youtube.com
|
|
192.168.3.1 i.ytimg.com
|
|
192.168.3.1 fonts.gstatic.com
|
|
192.168.3.1 www.gstatic.com
|
|
192.168.3.1 www.google.com
|
|
192.168.3.1 accounts.google.com
|
|
192.168.3.1 yt3.ggpht.com
|
|
192.168.3.1 rr1---sn-gxo5uxg-jqbl.googlevideo.com
|
|
192.168.3.1 rr2---sn-gxo5uxg-jqbl.googlevideo.com
|
|
192.168.3.1 rr4---sn-q4fl6nds.googlevideo.com
|
|
192.168.3.1 fr.wikipedia.org
|
|
192.168.3.1 upload.wikimedia.org
|
|
192.168.3.1 apple.com
|
|
192.168.3.1 www.apple.com
|
|
```
|
|
|
|
Install sa:
|
|
|
|
```bash
|
|
sudo apt install acct python3-invoke python3-fabric
|
|
sudo chmod +s /sbin/sa
|
|
```
|
|
|
|
Install OpenSSL with debug symbols:
|
|
|
|
```bash
|
|
# Options from Debian build
|
|
# Debian package libssl3t64 -> Developer Information -> buildd reproducibility -> trixie rbuild
|
|
# https://tests.reproducible-builds.org/debian/rb-pkg/trixie/amd64/openssl.html
|
|
/usr/bin/perl ./Configure --release -g --prefix=/usr --openssldir=/usr/lib/ssl --libdir=lib/x86_64-linux-gnu shared no-idea no-mdc2 no-rc5 no-ssl3 no-ssl3-method enable-rfc3779 enable-cms no-capieng no-rdrand enable-tfo enable-zstd enable-zlib enable-fips enable-ec_nistp_64_gcc_128
|
|
# Or, if OpenSSL 1.1:
|
|
/usr/bin/perl ./Configure --release -g --prefix=/usr --openssldir=/usr/lib/ssl --libdir=lib/x86_64-linux-gnu shared no-idea no-mdc2 no-rc5 no-ssl3 no-ssl3-method enable-rfc3779 enable-cms no-capieng no-rdrand enable-zlib enable-ec_nistp_64_gcc_128 linux-x86_64
|
|
```
|
|
|
|
To build rpxy with this openssl:
|
|
|
|
```bash
|
|
OPENSSL_LIB_DIR=/home/pi/reps/openssl-openssl-3.6.0/ OPENSSL_DIR=/home/pi/reps/openssl-openssl-3.6.0/ cargo build --release
|
|
```
|
|
|
|
Or: Backup your system's `libcrypto.so` and `libssl.so` and replace them with the new ones.
|
|
It would be simpler with `LD_PRELOAD` but Rust loads dynamic libraries in a particuliar way so it doesn't work.
|
|
|
|
Authorize non-root users to use perf:
|
|
|
|
```bash
|
|
sudo sysctl kernel.perf_event_paranoid=-1
|
|
```
|
|
|
|
Run:
|
|
|
|
```bash
|
|
python exp.py make local -c
|
|
python exp.py send local
|
|
python exp.py update-certs local
|
|
python exp.py run local
|
|
python plots.py prof <path/to/log>
|
|
```
|
|
|
|
## Problems
|
|
|
|
### Youtube
|
|
|
|
Youtube utilise des trucs aléatoires en `RANDOM.googlevideo.com` pour la vidéo. Cependant il y a quelques domaines utilisés qui ne changent pas, du moins sur un même navigateur avec la même vidéo et sur une courte période.
|
|
Avant d'enregistrer le trafic, il faut observer les domaines utilisés puis générer les certificats et les redirections en fonction.
|
|
|
|
## Notes
|
|
|
|
### CertVerify
|
|
|
|
CertVerify est l'extension dans le ServerHello qui signe la discussion passée avec la clé secrète du certificat.
|
|
|
|
Il a fallu désactiver la réutilisation de session, qui en TLS1.3 passe par le PSK, pour pouvoir mesurer le CertVerify.
|
|
|
|
## Size overhead and usage survey
|
|
|
|
```bash
|
|
openssl s_server -port 8000 -cert /dev/shm/exp/certs/prime256v1/wikipedia.org.crt -key /dev/shm/exp/certs/prime256v1/wikipedia.org.key
|
|
curl https://wikipedia.org --tlsv1.3 --curves x25519 --connect-to wikipedia.org:443:127.0.0.1:8000 -k
|
|
```
|
|
|
|
Get the most used domains here https://www.akamai.com/fr/security-research/akarank
|
|
|
|
```bash
|
|
python crawler.py crawl /dev/shm/top1K.csv
|
|
python crawler.py stat /dev/shm/crawl.json
|
|
```
|
|
|
|
## 0-RTT
|
|
|
|
```bash
|
|
echo "hello world" > /dev/shm/ed
|
|
openssl s_server -port 8000 -cert /dev/shm/exp/certs/prime256v1/wikipedia.org.crt -key /dev/shm/exp/certs/prime256v1/wikipedia.org.key -early_data
|
|
# First req, without early data
|
|
echo | openssl s_client -no-interactive -keylogfile /dev/shm/client.txt -sess_out sessions 127.0.0.1:8000
|
|
# Second req, using 0-RTT for early data
|
|
echo | openssl s_client -no-interactive -early_data /dev/shm/ed -keylogfile /dev/shm/client.txt -sess_in sessions 127.0.0.1:8000
|
|
```
|