Initial commit
This commit is contained in:
commit
a71491c068
13 changed files with 1470 additions and 0 deletions
270
README.md
Normal file
270
README.md
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
# 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.
|
||||
|
||||
### rpxy
|
||||
|
||||
Reverse-proxy utilisant RusTLS.
|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||
### self-signed cert
|
||||
|
||||
```bash
|
||||
openssl req -x509 -newkey rsa:2048 -keyout /tmp/foo.home.key -subj "/CN=foo.home/C=AT/ST=Lyon/L=Lyon/O=MyOrg" -out /tmp/foo.home.crt -nodes -sha256 -addext "subjectAltName=DNS:foo.home"
|
||||
```
|
||||
|
||||
### Client
|
||||
|
||||
Automatize experiments using [Selenium](https://www.selenium.dev/documentation/webdriver/getting_started/)
|
||||
|
||||
#### Experiment management
|
||||
|
||||
* Manager tells P2 what shared libs and rpxy binary to load.
|
||||
* Tell P1, P2, P3 what rpxy config to load.
|
||||
* Start measures.
|
||||
* Start Yocto (USB).
|
||||
* Start
|
||||
|
||||
#### Ad-hoc proxy?
|
||||
|
||||
Features:
|
||||
* Use RusTLS and any backend easily
|
||||
* Listen to plain HTTP or TLS (1.2 or 1.3)
|
||||
*
|
||||
|
||||
## 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
|
||||
* 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
|
||||
*
|
||||
|
||||
## Sources
|
||||
|
||||
* [RFC8446 (TLS 1.3)](https://datatracker.ietf.org/doc/html/rfc8446)
|
||||
|
||||
## Notes
|
||||
|
||||
Install sa on p2:
|
||||
|
||||
```bash
|
||||
sudo apt install acct
|
||||
sudo chmod +s /sbin/sa
|
||||
```
|
||||
|
||||
Override DNS in browser:
|
||||
|
||||
```bash
|
||||
firefox -P tlsbench
|
||||
```
|
||||
|
||||
In `about:config`, set `devtools.chrome.enabled` to `true`.
|
||||
Set default DNS in settings.
|
||||
In console:
|
||||
|
||||
```js
|
||||
const gOverride = Cc["@mozilla.org/network/native-dns-override;1"].getService(Ci.nsINativeDNSResolverOverride);
|
||||
gOverride.clearOverrides();
|
||||
var names = ["apple.com", "www.apple.com", "mzstatic.com", "youtube.com", "www.youtube.com", "i.ytimg.com", "fonts.gstatic.com", "www.google.com", "accounts.google.com", "yt3.ggpht.com", "www.gstatic.com"];
|
||||
for(var i in names) {
|
||||
gOverride.addIPOverride(names[i], "127.0.0.1");
|
||||
}
|
||||
```
|
||||
|
||||
Authorize rpxy to bind to ports 80 and 443:
|
||||
```bash
|
||||
sudo setcap CAP_NET_BIND_SERVICE=+eip rpxy_rustls_ring
|
||||
```
|
||||
|
||||
Add CA certificate on ArchLinux:
|
||||
```bash
|
||||
sudo cp /dev/shm/exp/certs/rsa2048/ca.crt /etc/ca-certificates/trust-source/anchors/ca-rsa2048.crt
|
||||
sudo cp /dev/shm/exp/certs/rsa3072/ca.crt /etc/ca-certificates/trust-source/anchors/ca-rsa3072.crt
|
||||
sudo cp /dev/shm/exp/certs/rsa4096/ca.crt /etc/ca-certificates/trust-source/anchors/ca-rsa4096.crt
|
||||
sudo cp /dev/shm/exp/certs/secp384r1/ca.crt /etc/ca-certificates/trust-source/anchors/ca-secp384r1.crt
|
||||
sudo chown root:root /etc/ca-certificates/trust-source/anchors/ca-*.crt
|
||||
sudo update-ca-trust extract
|
||||
```
|
||||
|
||||
```bash
|
||||
python exp.py make
|
||||
python exp.py send-setups
|
||||
python exp.py send-certs
|
||||
python exp.py run
|
||||
```
|
||||
|
||||
On Debian, update-certs says 0 certs added even if it has actually updated some certs. This step is still needed.
|
||||
|
||||
## Problems
|
||||
|
||||
### Youtube gives 502 bad gateway.
|
||||
|
||||
* Works with bare curl. (not hiding we're a bot)
|
||||
* We have same JA3 fingerprint as Firefox.
|
||||
* HTTP request is intact.
|
||||
* JA4 fingerprint different from Firefox but existing for some browsers.
|
||||
|
||||
### Modèle d'expérience à revoir
|
||||
|
||||
* Le relai d'une vidéo streaming avec TLS prend max 3% d'un cœur sur le Pi3, soit pas beaucoup plus que le bruit.
|
||||
* Il faudrait spammer avec plusieurs connexions pour voir un effet significatif.
|
||||
* On peut spammer le streaming vidéo, mais pas le reste (antibots).
|
||||
* On ne devrait pas spammer sur Renater...
|
||||
* Il faut donc tout faire en local.
|
||||
|
||||
Solutions :
|
||||
|
||||
* Copier les sites en statique et les servir avec Apache. => OK pour des sites propres genre Wikipedia, WordPress (à voir pour la pub)
|
||||
* Installer des instances => Peertube, WordPress
|
||||
* Copier le trafic et le rejouer => risque de demander beaucoup de dev
|
||||
|
||||
### 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.
|
||||
|
||||
## TODO
|
||||
|
||||
* Partie serveur sans TLS de netreplay -> sans SNI, il faut parser le HTTP >.<
|
||||
* exp.py: détecter la fin du replay
|
||||
* yoctowatt
|
||||
* mesures CPU, mémoire, bande passante sur p2
|
||||
* CPU: paquet acct, commande `sa -m`
|
||||
Loading…
Add table
Add a link
Reference in a new issue