| .gitignore | ||
| crawler.py | ||
| exp.py | ||
| exp_proxies.py | ||
| install-certs-arch.sh | ||
| install-certs-debian.sh | ||
| mkcacert.sh | ||
| mkcert.sh | ||
| mkcerts.sh | ||
| plots.py | ||
| powercap.c | ||
| profile.py | ||
| README.md | ||
| run.sh | ||
| servers.txt | ||
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
- GnuTLS
- NSS (used by Firefox) (?)
- opencryptoki (?)
- AWS-LC
- BoringSSL (Chrome, Android)
- LibreSSL
- SymCrypt (used by Windows) (install manually)
- 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
- Ciphers
- X.509
- Signature algorithm
- RSA2048
- RSA3072
- RSA4096
- EC 256
- EC 384
- SCT
- TODO !!!
- Signature algorithm
- TLS
- 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
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
Reproduce
Record
Authorize rpxy and netreplay to bind to ports 80 and 443:
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)
firefox -P tlsbench
In settings, disable DNS security.
In about:config, set:
devtools.chrome.enabledtotruenetwork.dns.forceResolveto127.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:
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:
./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:
sudo apt install acct dtach
sudo chmod +s /sbin/sa
Run:
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:
sudo apt install acct python3-invoke python3-fabric
sudo chmod +s /sbin/sa
Install OpenSSL with debug symbols:
# 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:
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:
sudo sysctl kernel.perf_event_paranoid=-1
Run:
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>
RAPL
gcc -O3 powercap.c -o powercap
sudo chmod u+s powercap
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
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
python crawler.py crawl /dev/shm/top1K.csv
python crawler.py stat /dev/shm/crawl.json
0-RTT
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