crawl, fixes
This commit is contained in:
parent
68435037e7
commit
f5145f80ea
7 changed files with 326 additions and 58 deletions
44
README.md
44
README.md
|
|
@ -158,6 +158,33 @@ sudo make install
|
||||||
* https://www.haproxy.com/blog/state-of-ssl-stacks
|
* https://www.haproxy.com/blog/state-of-ssl-stacks
|
||||||
* 2025
|
* 2025
|
||||||
* OpenSSL
|
* 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
|
||||||
|
|
||||||
## Sources
|
## Sources
|
||||||
|
|
||||||
|
|
@ -290,11 +317,12 @@ sudo chmod +s /sbin/sa
|
||||||
Install OpenSSL with debug symbols:
|
Install OpenSSL with debug symbols:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
#./Configure --release -g
|
|
||||||
# Options from Debian build
|
# Options from Debian build
|
||||||
# Debian package libssl3t64 -> Developer Information -> buildd reproducibility -> trixie rbuild
|
# Debian package libssl3t64 -> Developer Information -> buildd reproducibility -> trixie rbuild
|
||||||
# https://tests.reproducible-builds.org/debian/rb-pkg/trixie/amd64/openssl.html
|
# 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
|
/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
|
||||||
```
|
```
|
||||||
|
|
||||||
Backup your system's `libcrypto.so` and `libssl.so` and replace them with the new ones.
|
Backup your system's `libcrypto.so` and `libssl.so` and replace them with the new ones.
|
||||||
|
|
@ -330,3 +358,17 @@ Avant d'enregistrer le trafic, il faut observer les domaines utilisés puis gén
|
||||||
CertVerify est l'extension dans le ServerHello qui signe la discussion passée avec la clé secrète du certificat.
|
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.
|
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
|
||||||
|
```
|
||||||
|
|
|
||||||
94
crawler.py
Normal file
94
crawler.py
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
import json,re, subprocess, sys, threading, time
|
||||||
|
|
||||||
|
BATCH = 50
|
||||||
|
TIMEOUT = 4
|
||||||
|
CAPTURES = {
|
||||||
|
"read_bytes": "SSL handshake has read (\\d+) bytes and written \\d+ bytes\n",
|
||||||
|
"written_bytes": "SSL handshake has read \\d+ bytes and written (\\d+) bytes\n",
|
||||||
|
"cert_sig": "Peer signature type: ([a-zA-Z0-9_.-]+)\n",
|
||||||
|
"cert_pk_size": "Server public key is (\\d+) bit\n",
|
||||||
|
"kx": "(?:Negotiated TLS1\\.3 group|Peer Temp Key): ([a-zA-Z0-9_.-]+)(?:\n|,)",
|
||||||
|
"cipher": "Cipher is ([a-zA-Z0-9_.-]+)\n",
|
||||||
|
"protocol": "Protocol: ([a-zA-Z0-9_.-]+)\n",
|
||||||
|
}
|
||||||
|
|
||||||
|
lock = threading.Lock()
|
||||||
|
results = {}
|
||||||
|
subs = []
|
||||||
|
|
||||||
|
def probe(domain, ossl):
|
||||||
|
# End of input data, cleanly stops the session and the process
|
||||||
|
ossl.stdin.write(b"")
|
||||||
|
ossl.stdin.close()
|
||||||
|
|
||||||
|
results[domain] = output = ossl.stdout.read().decode()
|
||||||
|
|
||||||
|
ossl.kill()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if sys.argv[1] == "crawl":
|
||||||
|
threads = []
|
||||||
|
f = open(sys.argv[2], "r")
|
||||||
|
for line in f.readlines()[1:]:
|
||||||
|
#line = line.removesuffix("\n")
|
||||||
|
line = line[:line.find(",")-1]
|
||||||
|
print("start", line)
|
||||||
|
addr = f"{line}:443"
|
||||||
|
ossl = subprocess.Popen(["openssl", "s_client", "-no-interactive", addr], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
t = threading.Thread(target=probe, args=(line, ossl,))
|
||||||
|
threads.append((t, ossl, time.time()))
|
||||||
|
time.sleep(0.05)
|
||||||
|
t.start()
|
||||||
|
if len(threads) >= BATCH:
|
||||||
|
print("wait")
|
||||||
|
for (t, ossl, start) in threads:
|
||||||
|
t.join(max(0, TIMEOUT - (time.time() - start)))
|
||||||
|
try:
|
||||||
|
ossl.kill()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
threads.clear()
|
||||||
|
print("waited")
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
for (t, ossl, start) in threads:
|
||||||
|
t.join(max(0, TIMEOUT - (time.time() - start)))
|
||||||
|
try:
|
||||||
|
ossl.kill()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
threads.clear()
|
||||||
|
|
||||||
|
print("finished")
|
||||||
|
|
||||||
|
f = open("/dev/shm/crawl.json", "w")
|
||||||
|
json.dump(results, f)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
print("written")
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
elif sys.argv[1] == "stat":
|
||||||
|
regexes = {}
|
||||||
|
for r in CAPTURES:
|
||||||
|
regexes[r] = re.compile(CAPTURES[r])
|
||||||
|
stats = {}
|
||||||
|
f = open(sys.argv[2], "r")
|
||||||
|
c = json.load(f)
|
||||||
|
for domain in c:
|
||||||
|
for r in CAPTURES:
|
||||||
|
try:
|
||||||
|
val = regexes[r].finditer(c[domain]).__next__().group(1)
|
||||||
|
#print(r, val)
|
||||||
|
if r in ["domain", "read_bytes", "written_bytes"]:
|
||||||
|
continue
|
||||||
|
if not r in stats:
|
||||||
|
stats[r] = {}
|
||||||
|
if not val in stats[r]:
|
||||||
|
stats[r][val] = 1
|
||||||
|
else:
|
||||||
|
stats[r][val] += 1
|
||||||
|
except StopIteration:
|
||||||
|
pass
|
||||||
|
#print("Not found:", line, r)
|
||||||
|
print(stats)
|
||||||
113
exp.py
113
exp.py
|
|
@ -2,18 +2,49 @@
|
||||||
import os, sys, subprocess
|
import os, sys, subprocess
|
||||||
|
|
||||||
CONFIGS = {
|
CONFIGS = {
|
||||||
# placid -> pi3
|
# i7-4790 local
|
||||||
"pi": {
|
"local": {
|
||||||
"experiments": [
|
"experiments": [
|
||||||
"impl-cipher-ver",
|
"impl-cipher-ver",
|
||||||
"impl-cert-ver",
|
"impl-cert-ver",
|
||||||
"impl-kex-ver",
|
"impl-kex-ver",
|
||||||
],
|
],
|
||||||
|
"setups": [
|
||||||
|
"none-local",
|
||||||
|
"client-local",
|
||||||
|
"server-local",
|
||||||
|
],
|
||||||
|
"records": [
|
||||||
|
{ "filename": "youtube", "repeat": 1 },
|
||||||
|
],
|
||||||
|
"repodir": "/home/tuxmain/reps/tlsbench",
|
||||||
|
"expdir": "/dev/shm/exp",
|
||||||
|
"log_backup_dir": "/home/tuxmain",
|
||||||
|
"p2_hostname": "localhost",
|
||||||
|
"p2_addr": "127.0.0.1",
|
||||||
|
"p2_repodir": "/home/tuxmain/reps/tlsbench",
|
||||||
|
"wattmeter": False,
|
||||||
|
"perf": True,
|
||||||
|
"perf_dir": "/home/tuxmain/.cache/exp",
|
||||||
|
"p3_suffix": ".localhost",
|
||||||
|
"p3_port_plain": 8080,
|
||||||
|
"p3_port_tls": 8443,
|
||||||
|
},
|
||||||
|
# i7-4790 -> pi3
|
||||||
|
"pi3": {
|
||||||
|
"experiments": [
|
||||||
|
#"impl-cipher-ver",
|
||||||
|
"impl-cert-ver",
|
||||||
|
#"impl-kex-ver",
|
||||||
|
],
|
||||||
"setups": [
|
"setups": [
|
||||||
"none",
|
"none",
|
||||||
"client",
|
"client",
|
||||||
"server",
|
"server",
|
||||||
],
|
],
|
||||||
|
"records": [
|
||||||
|
{ "filename": "youtube", "repeat": 100 },
|
||||||
|
],
|
||||||
"repodir": "/home/tuxmain/reps/tlsbench",
|
"repodir": "/home/tuxmain/reps/tlsbench",
|
||||||
"expdir": "/dev/shm/exp",
|
"expdir": "/dev/shm/exp",
|
||||||
"log_backup_dir": "/home/tuxmain",
|
"log_backup_dir": "/home/tuxmain",
|
||||||
|
|
@ -29,8 +60,7 @@ CONFIGS = {
|
||||||
"p3_port_tls": 443,
|
"p3_port_tls": 443,
|
||||||
"idle": "idle - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 -",
|
"idle": "idle - - - - - - 600.000081539154 0.0 896 4792 0.5399999999999991 -",
|
||||||
},
|
},
|
||||||
# placid local
|
"pi3-local": {
|
||||||
"local": {
|
|
||||||
"experiments": [
|
"experiments": [
|
||||||
"impl-cipher-ver",
|
"impl-cipher-ver",
|
||||||
"impl-cert-ver",
|
"impl-cert-ver",
|
||||||
|
|
@ -41,21 +71,24 @@ CONFIGS = {
|
||||||
"client-local",
|
"client-local",
|
||||||
"server-local",
|
"server-local",
|
||||||
],
|
],
|
||||||
"repodir": "/home/tuxmain/reps/tlsbench",
|
"records": [
|
||||||
|
{ "filename": "wikipedia", "repeat": 5 },
|
||||||
|
],
|
||||||
|
"repodir": "/home/exp/exp",
|
||||||
"expdir": "/dev/shm/exp",
|
"expdir": "/dev/shm/exp",
|
||||||
"log_backup_dir": "/home/tuxmain",
|
"log_backup_dir": "/home/exp",
|
||||||
"p2_hostname": "localhost",
|
"p2_hostname": "localhost",
|
||||||
"p2_addr": "127.0.0.1",
|
"p2_addr": "127.0.0.1",
|
||||||
"p2_repodir": "/home/tuxmain/reps/tlsbench",
|
"p2_repodir": "/home/exp/exp",
|
||||||
"wattmeter": False,
|
"wattmeter": False,
|
||||||
"perf": True,
|
"perf": True,
|
||||||
"perf_dir": "/home/tuxmain/.cache/exp",
|
"perf_dir": "/home/exp/.cache/exp",
|
||||||
"p3_suffix": ".localhost",
|
"p3_suffix": ".localhost",
|
||||||
"p3_port_plain": 8080,
|
"p3_port_plain": 8080,
|
||||||
"p3_port_tls": 8443,
|
"p3_port_tls": 8443,
|
||||||
},
|
},
|
||||||
# placid -> pifou
|
# i7-4790 -> core2
|
||||||
"pifou": {
|
"core2": {
|
||||||
"experiments": [
|
"experiments": [
|
||||||
"impl-cipher-ver",
|
"impl-cipher-ver",
|
||||||
"impl-cert-ver",
|
"impl-cert-ver",
|
||||||
|
|
@ -66,13 +99,17 @@ CONFIGS = {
|
||||||
"client",
|
"client",
|
||||||
"server",
|
"server",
|
||||||
],
|
],
|
||||||
|
"records": [
|
||||||
|
{ "filename": "wikipedia", "repeat": 400 },
|
||||||
|
{ "filename": "youtube", "repeat": 100 },
|
||||||
|
],
|
||||||
"repodir": "/home/tuxmain/reps/tlsbench",
|
"repodir": "/home/tuxmain/reps/tlsbench",
|
||||||
"expdir": "/dev/shm/exp",
|
"expdir": "/dev/shm/exp",
|
||||||
"log_backup_dir": "/home/tuxmain",
|
"log_backup_dir": "/home/tuxmain",
|
||||||
"p2_hostname": "192.168.3.3",
|
"p2_hostname": "192.168.3.3",
|
||||||
"p2_addr": "192.168.3.3",
|
"p2_addr": "192.168.3.3",
|
||||||
"p2_ssh": "exp@192.168.3.3",
|
"p2_ssh": "exp@192.168.3.3",
|
||||||
"p2_psw": "exp",
|
"p2_psw": None,
|
||||||
"p2_repodir": "/home/exp/exp",
|
"p2_repodir": "/home/exp/exp",
|
||||||
"wattmeter": True,
|
"wattmeter": True,
|
||||||
"perf": False,
|
"perf": False,
|
||||||
|
|
@ -81,8 +118,7 @@ CONFIGS = {
|
||||||
"p3_port_tls": 443,
|
"p3_port_tls": 443,
|
||||||
"idle": "idle - - - - - - 600.0001013278961 0.0 735 4942 1.7759999999999962 -",
|
"idle": "idle - - - - - - 600.0001013278961 0.0 735 4942 1.7759999999999962 -",
|
||||||
},
|
},
|
||||||
# placid local
|
"core2-local": {
|
||||||
"pifou-local": {
|
|
||||||
"experiments": [
|
"experiments": [
|
||||||
"impl-cipher-ver",
|
"impl-cipher-ver",
|
||||||
"impl-cert-ver",
|
"impl-cert-ver",
|
||||||
|
|
@ -93,6 +129,9 @@ CONFIGS = {
|
||||||
"client-local",
|
"client-local",
|
||||||
"server-local",
|
"server-local",
|
||||||
],
|
],
|
||||||
|
"records": [
|
||||||
|
{ "filename": "wikipedia", "repeat": 10 },
|
||||||
|
],
|
||||||
"repodir": "/home/exp/exp",
|
"repodir": "/home/exp/exp",
|
||||||
"expdir": "/dev/shm/exp",
|
"expdir": "/dev/shm/exp",
|
||||||
"log_backup_dir": "/home/exp",
|
"log_backup_dir": "/home/exp",
|
||||||
|
|
@ -132,13 +171,6 @@ DOMAINS_ = [
|
||||||
"videos.domainepublic.net",
|
"videos.domainepublic.net",
|
||||||
]
|
]
|
||||||
|
|
||||||
RECORDS = [
|
|
||||||
#{ "filename": "youtube", "repeat": 100 },
|
|
||||||
#{ "filename": "peertube", "repeat": 10 },
|
|
||||||
{ "filename": "wikipedia", "repeat": 400 },
|
|
||||||
#{ "filename": "apple", "repeat": 1000 },
|
|
||||||
#{ "filename": "google", "repeat": 1000 },
|
|
||||||
]
|
|
||||||
CERT_SIGN_ALGS = [
|
CERT_SIGN_ALGS = [
|
||||||
"prime256v1", # widely used
|
"prime256v1", # widely used
|
||||||
"secp384r1", # rarely used but supported by browsers because it's NIST standard
|
"secp384r1", # rarely used but supported by browsers because it's NIST standard
|
||||||
|
|
@ -146,7 +178,7 @@ CERT_SIGN_ALGS = [
|
||||||
"rsa2048", "rsa3072", "rsa4096", # widely used
|
"rsa2048", "rsa3072", "rsa4096", # widely used
|
||||||
]
|
]
|
||||||
IMPLS = [
|
IMPLS = [
|
||||||
"aws_lc_rs", # Amazon's Rust crypto widely used in Rust stuff
|
"aws_lc", # Amazon's Rust crypto widely used in Rust stuff
|
||||||
"boring", # Google's fork of OpenSSL used in Chrome and Android
|
"boring", # Google's fork of OpenSSL used in Chrome and Android
|
||||||
"openssl", # widely used
|
"openssl", # widely used
|
||||||
"ring", # used in most Rust stuff
|
"ring", # used in most Rust stuff
|
||||||
|
|
@ -171,6 +203,9 @@ KEXES = [
|
||||||
"X25519",
|
"X25519",
|
||||||
"SECP256R1",
|
"SECP256R1",
|
||||||
"SECP384R1",
|
"SECP384R1",
|
||||||
|
"X25519MLKEM768",
|
||||||
|
"SECP256R1MLKEM768",
|
||||||
|
"MLKEM768",
|
||||||
]
|
]
|
||||||
|
|
||||||
# Testing all combinations would be too much. Instead we isolate independent parts.
|
# Testing all combinations would be too much. Instead we isolate independent parts.
|
||||||
|
|
@ -178,7 +213,6 @@ EXPERIMENTS = {
|
||||||
# Compare ciphers among implementations and TLS versions
|
# Compare ciphers among implementations and TLS versions
|
||||||
"impl-cipher-ver": {
|
"impl-cipher-ver": {
|
||||||
"impls": IMPLS,
|
"impls": IMPLS,
|
||||||
"records": RECORDS,
|
|
||||||
"ciphers": [
|
"ciphers": [
|
||||||
"AES_128_GCM_SHA256",
|
"AES_128_GCM_SHA256",
|
||||||
"AES_256_GCM_SHA384",
|
"AES_256_GCM_SHA384",
|
||||||
|
|
@ -193,7 +227,6 @@ EXPERIMENTS = {
|
||||||
# Compare signatures among implementations and TLS versions
|
# Compare signatures among implementations and TLS versions
|
||||||
"impl-cert-ver": {
|
"impl-cert-ver": {
|
||||||
"impls": IMPLS,
|
"impls": IMPLS,
|
||||||
"records": RECORDS,
|
|
||||||
"ciphers": [
|
"ciphers": [
|
||||||
"AES_128_GCM_SHA256",
|
"AES_128_GCM_SHA256",
|
||||||
#"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
#"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
|
|
@ -210,17 +243,22 @@ EXPERIMENTS = {
|
||||||
# Compare key exchange groups among implementations and TLS versions
|
# Compare key exchange groups among implementations and TLS versions
|
||||||
"impl-kex-ver": {
|
"impl-kex-ver": {
|
||||||
"impls": IMPLS,
|
"impls": IMPLS,
|
||||||
"records": RECORDS,
|
|
||||||
"ciphers": [
|
"ciphers": [
|
||||||
"AES_128_GCM_SHA256",
|
"AES_128_GCM_SHA256",
|
||||||
#"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
#"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
],
|
],
|
||||||
"kexes": ["X25519", "SECP256R1", "SECP384R1"],
|
"kexes": [
|
||||||
|
"X25519",
|
||||||
|
"SECP256R1",
|
||||||
|
"SECP384R1",
|
||||||
|
"X25519MLKEM768",
|
||||||
|
"SECP256R1MLKEM768",
|
||||||
|
"MLKEM768",
|
||||||
|
],
|
||||||
"cert": ["prime256v1"],
|
"cert": ["prime256v1"],
|
||||||
},
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"impls": IMPLS,
|
"impls": IMPLS,
|
||||||
"records": RECORDS,
|
|
||||||
"ciphers": [
|
"ciphers": [
|
||||||
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256",
|
||||||
#"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
#"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||||
|
|
@ -230,6 +268,16 @@ EXPERIMENTS = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Some algorithms are not available in all implementations
|
||||||
|
def alg_filter(kex, cert, cipher, impl):
|
||||||
|
if "MLKEM" in kex and impl != "openssl" and impl != "aws_lc":
|
||||||
|
return False
|
||||||
|
if kex == "SECP256R1MLKEM768" and impl == "openssl":
|
||||||
|
return False
|
||||||
|
if cert == "secp384r1" and impl == "boring":
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
DOMAINS = []
|
DOMAINS = []
|
||||||
for domain in DOMAINS_:
|
for domain in DOMAINS_:
|
||||||
if not domain in DOMAINS:
|
if not domain in DOMAINS:
|
||||||
|
|
@ -644,11 +692,13 @@ def run_exp(config, only_record=None, idle=False):
|
||||||
ssh_run(ssh, f"python {p2_path}/exp.py cert {config_name} {alg}")
|
ssh_run(ssh, f"python {p2_path}/exp.py cert {config_name} {alg}")
|
||||||
for kex in exp["kexes"]:
|
for kex in exp["kexes"]:
|
||||||
for cipher in exp["ciphers"]:
|
for cipher in exp["ciphers"]:
|
||||||
|
if not alg_filter(kex, alg, cipher, impl):
|
||||||
|
continue
|
||||||
for setup in config["setups"]:
|
for setup in config["setups"]:
|
||||||
if SETUPS[setup]["tls_invariant"] and not first_set:
|
if SETUPS[setup]["tls_invariant"] and not first_set:
|
||||||
continue
|
continue
|
||||||
setupdir = expdir+"setups/"+setup
|
setupdir = expdir+"setups/"+setup
|
||||||
for record in exp["records"]:
|
for record in config["records"]:
|
||||||
print(f"EXPERIMENT {expname}: {impl} {alg} {kex} {cipher} {setup}")
|
print(f"EXPERIMENT {expname}: {impl} {alg} {kex} {cipher} {setup}")
|
||||||
p2_rpxy_config = SETUPS[setup]["rpxy_config"]
|
p2_rpxy_config = SETUPS[setup]["rpxy_config"]
|
||||||
vars = {"CIPHERS": cipher, "KEXES": kex, "RUST_LOG": "warning"}
|
vars = {"CIPHERS": cipher, "KEXES": kex, "RUST_LOG": "warning"}
|
||||||
|
|
@ -703,7 +753,7 @@ def run_exp(config, only_record=None, idle=False):
|
||||||
#time.sleep(30)
|
#time.sleep(30)
|
||||||
#sh("killall netreplay")
|
#sh("killall netreplay")
|
||||||
try:
|
try:
|
||||||
ssh_run(ssh, f"rm /dev/shm/access.log /dev/shm/rpxy.log")
|
#ssh_run(ssh, f"rm /dev/shm/access.log /dev/shm/rpxy.log")
|
||||||
pass
|
pass
|
||||||
except invoke.exceptions.UnexpectedExit as e:
|
except invoke.exceptions.UnexpectedExit as e:
|
||||||
pass
|
pass
|
||||||
|
|
@ -841,14 +891,15 @@ Run options:
|
||||||
exps = 0
|
exps = 0
|
||||||
for expname in config["experiments"]:
|
for expname in config["experiments"]:
|
||||||
exp = config["experiments"][expname]
|
exp = config["experiments"][expname]
|
||||||
exps += len(exp["impls"]) * len(exp["cert"]) * len(exp["kexes"]) * len(exp["ciphers"]) * len(exp["records"])
|
exps += len(exp["impls"]) * len(exp["cert"]) * len(exp["kexes"]) * len(exp["ciphers"]) * len(config["records"])
|
||||||
print("Experiments to make:", exps * len(config["setups"]))
|
print("Experiments to make:", exps * len(config["setups"]))
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
import time
|
import time
|
||||||
import invoke
|
|
||||||
import re
|
import re
|
||||||
import fabric
|
if "p2_ssh" in config:
|
||||||
|
import invoke
|
||||||
|
import fabric
|
||||||
|
|
||||||
if config["wattmeter"]:
|
if config["wattmeter"]:
|
||||||
import yoctopuce
|
import yoctopuce
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ CERT_SIGN_ALGS = [
|
||||||
"rsa2048", "rsa3072", "rsa4096", # widely used
|
"rsa2048", "rsa3072", "rsa4096", # widely used
|
||||||
]
|
]
|
||||||
IMPLS = [
|
IMPLS = [
|
||||||
#"aws_lc_rs", # Amazon's Rust crypto widely used in Rust stuff
|
#"aws_lc", # Amazon's Rust crypto widely used in Rust stuff
|
||||||
#"boring", # Google's fork of OpenSSL used in Chrome and Android
|
#"boring", # Google's fork of OpenSSL used in Chrome and Android
|
||||||
#"openssl", # widely used
|
#"openssl", # widely used
|
||||||
"ring", # used in most Rust stuff
|
"ring", # used in most Rust stuff
|
||||||
|
|
|
||||||
113
plots.py
113
plots.py
|
|
@ -3,20 +3,23 @@ import profile
|
||||||
|
|
||||||
# Nice labels for algorithms of all kinds
|
# Nice labels for algorithms of all kinds
|
||||||
ALG_LABEL = {
|
ALG_LABEL = {
|
||||||
"AES_128_GCM_SHA256": "AES128",
|
"AES_128_GCM_SHA256": "aes128",
|
||||||
"AES_256_GCM_SHA384": "AES256",
|
"AES_256_GCM_SHA384": "aes256",
|
||||||
"CHACHA20_POLY1305_SHA256": "CHACHA20",
|
"CHACHA20_POLY1305_SHA256": "chacha20",
|
||||||
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256": "AES128",
|
"ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,ECDHE_RSA_WITH_AES_128_GCM_SHA256": "aes128",
|
||||||
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384": "AES256",
|
"ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,ECDHE_RSA_WITH_AES_256_GCM_SHA384": "aes256",
|
||||||
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": "CHACHA20",
|
"ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256": "chacha20",
|
||||||
"prime256v1": "prime256v1",
|
"prime256v1": "p256",
|
||||||
"secp384r1": "secp384r1",
|
"secp384r1": "p384",
|
||||||
"rsa2048": "rsa2048",
|
"rsa2048": "rsa2048",
|
||||||
"rsa3072": "rsa3072",
|
"rsa3072": "rsa3072",
|
||||||
"rsa4096": "rsa4096",
|
"rsa4096": "rsa4096",
|
||||||
"X25519": "X25519",
|
"X25519": "x25519",
|
||||||
"SECP256R1": "SECP256R1",
|
"SECP256R1": "p256",
|
||||||
"SECP384R1": "SECP384R1"
|
"SECP384R1": "p384",
|
||||||
|
"X25519MLKEM768": "x25519mlkem",
|
||||||
|
"SECP256R1MLKEM768": "p256mlkem",
|
||||||
|
"MLKEM768": "mlkem",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Nice labels for TLS versions using ciphers
|
# Nice labels for TLS versions using ciphers
|
||||||
|
|
@ -56,6 +59,10 @@ CRITERION_TITLE = {
|
||||||
"kex": "key exchange"
|
"kex": "key exchange"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def impl_title(impl):
|
||||||
|
# Gnuplot does not escape underscores when generating tex
|
||||||
|
return impl.replace("_", "-")
|
||||||
|
|
||||||
# Where gnuplot files, data files and images are output
|
# Where gnuplot files, data files and images are output
|
||||||
PLOTS_DIR = "/dev/shm/plots"
|
PLOTS_DIR = "/dev/shm/plots"
|
||||||
|
|
||||||
|
|
@ -87,6 +94,9 @@ set grid y lt 1 lw .75 lc "gray"
|
||||||
plot \
|
plot \
|
||||||
newhistogram "", "{plots_dir}/{object}_by_{criterion}_{side}_{record}.dat" using 2:xticlabels(1) notitle col, \
|
newhistogram "", "{plots_dir}/{object}_by_{criterion}_{side}_{record}.dat" using 2:xticlabels(1) notitle col, \
|
||||||
newhistogram "", "{plots_dir}/{object}_by_{criterion}_{side}_{record}.dat" using 3:xticlabels(1) title col{cluster}
|
newhistogram "", "{plots_dir}/{object}_by_{criterion}_{side}_{record}.dat" using 3:xticlabels(1) title col{cluster}
|
||||||
|
set term cairolatex pdf
|
||||||
|
set output "{plots_dir}/{object}_by_{criterion}_{side}_{record}.tex"
|
||||||
|
replot
|
||||||
""".format(plots_dir=PLOTS_DIR, cluster=cluster, **kwargs))
|
""".format(plots_dir=PLOTS_DIR, cluster=cluster, **kwargs))
|
||||||
f.close()
|
f.close()
|
||||||
os.system("gnuplot {plots_dir}/{object}_by_{criterion}_{side}_{record}.gnuplot".format(plots_dir=PLOTS_DIR, **kwargs))
|
os.system("gnuplot {plots_dir}/{object}_by_{criterion}_{side}_{record}.gnuplot".format(plots_dir=PLOTS_DIR, **kwargs))
|
||||||
|
|
@ -108,14 +118,23 @@ set style fill solid 1.0 border lt -1
|
||||||
set style histogram rowstacked
|
set style histogram rowstacked
|
||||||
set style data histograms
|
set style data histograms
|
||||||
set title font "CMU Sans Serif,12" "{object_title} by {criterion_title} ({record}, {side}{machine}) ({unit})"
|
set title font "CMU Sans Serif,12" "{object_title} by {criterion_title} ({record}, {side}{machine}) ({unit})"
|
||||||
set xtics border in scale 0,0 nomirror noenhanced rotate by -15 autojustify
|
set xtics border in scale 0,0 nomirror noenhanced rotate by 30 right
|
||||||
|
set lmargin 9
|
||||||
|
set rmargin 1
|
||||||
|
set bmargin 5
|
||||||
|
set tmargin 2.5
|
||||||
set key fixed left top vertical Left noenhanced autotitle nobox invert reverse opaque
|
set key fixed left top vertical Left noenhanced autotitle nobox invert reverse opaque
|
||||||
set colorbox vertical origin screen 0.9, 0.2 size screen 0.05, 0.6 front noinvert bdefault
|
set colorbox vertical origin screen 0.9, 0.2 size screen 0.05, 0.6 front noinvert bdefault
|
||||||
set xrange [ * : * ] noreverse writeback
|
set xrange [ * : * ] noreverse writeback
|
||||||
set yrange [ 0 : * ]
|
set yrange [ 0 : * ]
|
||||||
set grid y lt 1 lw .75 lc "gray"
|
set grid y lt 1 lw .75 lc "gray"
|
||||||
plot for [i=2:{nb_functions}] "{plots_dir}/{object}_by_{criterion}_{side}_{record}.dat" using i:xticlabels(1) title col
|
plot for [i=2:{nb_functions}] "{plots_dir}/{object}_by_{criterion}_{side}_{record}.dat" using i:xticlabels(1) title col
|
||||||
""".format(plots_dir=PLOTS_DIR, cluster=cluster, **kwargs))
|
#set term cairolatex pdf
|
||||||
|
set term pict2e font ",10"
|
||||||
|
set output "{plots_dir}/{object}_by_{criterion}_{side}_{record}.tex"
|
||||||
|
set key font ",10" spacing 0.8
|
||||||
|
replot
|
||||||
|
""".format(plots_dir=PLOTS_DIR, cluster=cluster, **kwargs).replace("aws_lc", "aws-lc"))
|
||||||
f.close()
|
f.close()
|
||||||
os.system("gnuplot {plots_dir}/{object}_by_{criterion}_{side}_{record}.gnuplot".format(plots_dir=PLOTS_DIR, **kwargs))
|
os.system("gnuplot {plots_dir}/{object}_by_{criterion}_{side}_{record}.gnuplot".format(plots_dir=PLOTS_DIR, **kwargs))
|
||||||
|
|
||||||
|
|
@ -145,19 +164,26 @@ def make_log_plot(logs, exp, criterion, side, obj, record, machine=None):
|
||||||
if log["impl"] not in impls:
|
if log["impl"] not in impls:
|
||||||
impls.append(log["impl"])
|
impls.append(log["impl"])
|
||||||
impls.sort()
|
impls.sort()
|
||||||
f.write("{} none {}\n".format(criterion, " ".join(impls)))
|
f.write("{} none {}\n".format(criterion, " ".join([impl_title(impl) for impl in impls])))
|
||||||
f.write(plain_line+" -"*len(impls)+"\n")
|
f.write(plain_line+" -"*len(impls)+"\n")
|
||||||
for cipher in ciphers:
|
for cipher in ciphers:
|
||||||
for impl in impls:
|
for impl in impls:
|
||||||
if impl not in ciphers[cipher]:
|
if impl not in ciphers[cipher]:
|
||||||
ciphers[cipher][impl] = 0
|
ciphers[cipher][impl] = 0
|
||||||
f.write("{}({}) - {}\n".format(
|
"""f.write("{}({}) - {}\n".format(
|
||||||
ALG_LABEL[cipher],
|
ALG_LABEL[cipher],
|
||||||
VER_LABEL[log["cipher"]],
|
VER_LABEL[log["cipher"]],
|
||||||
" ".join([
|
" ".join([
|
||||||
str(ciphers[cipher][impl])
|
str(ciphers[cipher][impl])
|
||||||
for impl in impls
|
for impl in impls
|
||||||
]),
|
]),
|
||||||
|
))"""
|
||||||
|
f.write("{} - {}\n".format(
|
||||||
|
ALG_LABEL[cipher],
|
||||||
|
" ".join([
|
||||||
|
str(ciphers[cipher][impl])
|
||||||
|
for impl in impls
|
||||||
|
]),
|
||||||
))
|
))
|
||||||
f.close()
|
f.close()
|
||||||
gnuplot_histogram(
|
gnuplot_histogram(
|
||||||
|
|
@ -186,7 +212,7 @@ def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, m
|
||||||
profile_results = profile.extract_from_file(svg_filename)
|
profile_results = profile.extract_from_file(svg_filename)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print(f"Cannot read {svg_filename}")
|
print(f"Cannot read {svg_filename}")
|
||||||
return
|
continue
|
||||||
print(profile_results)
|
print(profile_results)
|
||||||
for function in profile_results:
|
for function in profile_results:
|
||||||
if function not in functions:
|
if function not in functions:
|
||||||
|
|
@ -198,7 +224,7 @@ def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, m
|
||||||
})
|
})
|
||||||
f.write("{} {}\n".format(criterion, " ".join(functions)))
|
f.write("{} {}\n".format(criterion, " ".join(functions)))
|
||||||
for run in runs:
|
for run in runs:
|
||||||
f.write("\"{} {}({})\" {}\n".format(
|
"""f.write("\"{} {}({})\" {}\n".format(
|
||||||
run["impl"],
|
run["impl"],
|
||||||
ALG_LABEL[run[criterion]],
|
ALG_LABEL[run[criterion]],
|
||||||
VER_LABEL[log["cipher"]],
|
VER_LABEL[log["cipher"]],
|
||||||
|
|
@ -206,6 +232,14 @@ def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, m
|
||||||
str(run["functions"][function][0])
|
str(run["functions"][function][0])
|
||||||
for function in functions
|
for function in functions
|
||||||
]),
|
]),
|
||||||
|
))"""
|
||||||
|
f.write("\"{} {}\" {}\n".format(
|
||||||
|
impl_title(run["impl"]),
|
||||||
|
ALG_LABEL[run[criterion]],
|
||||||
|
" ".join([
|
||||||
|
str(run["functions"][function][0])
|
||||||
|
for function in functions
|
||||||
|
]),
|
||||||
))
|
))
|
||||||
f.close()
|
f.close()
|
||||||
gnuplot_stacked_histogram(
|
gnuplot_stacked_histogram(
|
||||||
|
|
@ -220,6 +254,46 @@ def make_profile_plot(logs, exp, criterion, side, record, no_flamegraph=False, m
|
||||||
machine=machine
|
machine=machine
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Are CPU and energy proportional
|
||||||
|
def make_linear_regression(logs):
|
||||||
|
idle_cpu = None
|
||||||
|
idle_energy = None
|
||||||
|
for log in logs:
|
||||||
|
if log["exp"] == "idle":
|
||||||
|
idle_cpu = float(log["cpu"]) / float(log["time"])
|
||||||
|
idle_energy = float(log["Wh"]) / float(log["time"])
|
||||||
|
break
|
||||||
|
|
||||||
|
samples_cpu = {"global":[]}
|
||||||
|
samples_energy = {"global":[]}
|
||||||
|
for log in logs:
|
||||||
|
if log["impl"] == "-":
|
||||||
|
continue
|
||||||
|
sample_cpu = float(log["cpu"]) - idle_cpu * float(log["time"])
|
||||||
|
sample_energy = float(log["Wh"]) - idle_energy * float(log["time"])
|
||||||
|
samples_cpu["global"].append(sample_cpu)
|
||||||
|
samples_energy["global"].append(sample_energy)
|
||||||
|
if log["impl"] not in samples_cpu:
|
||||||
|
samples_cpu[log["impl"]] = []
|
||||||
|
samples_energy[log["impl"]] = []
|
||||||
|
samples_cpu[log["impl"]].append(sample_cpu)
|
||||||
|
samples_energy[log["impl"]].append(sample_energy)
|
||||||
|
print("Pearson correlation coefficients (energy/cpu)")
|
||||||
|
results = {}
|
||||||
|
for impl in samples_cpu:
|
||||||
|
res = stats.linregress(samples_cpu[impl], samples_energy[impl])
|
||||||
|
print(impl, "\t", res.rvalue)
|
||||||
|
results[impl] = res
|
||||||
|
if impl != "global":
|
||||||
|
plt.plot(samples_cpu[impl], samples_energy[impl], 'o', label=impl)
|
||||||
|
#plt.plot(samples_cpu["global"], samples_energy["global"], 'o', label='samples')
|
||||||
|
plt.plot(samples_cpu["global"], res.intercept + res.slope*np.array(samples_cpu["global"]), 'r', label='fitted line')
|
||||||
|
plt.xlabel("CPU (s)")
|
||||||
|
plt.ylabel("Energy (Wh)")
|
||||||
|
plt.legend()
|
||||||
|
#plt.show()
|
||||||
|
plt.savefig(f"{PLOTS_DIR}/correlation_energy_cpu.png")
|
||||||
|
|
||||||
def getargv(arg:str, default="", n:int=1, args:list=sys.argv):
|
def getargv(arg:str, default="", n:int=1, args:list=sys.argv):
|
||||||
if arg in args and len(args) > args.index(arg)+n:
|
if arg in args and len(args) > args.index(arg)+n:
|
||||||
return args[args.index(arg)+n]
|
return args[args.index(arg)+n]
|
||||||
|
|
@ -267,3 +341,8 @@ if __name__ == "__main__":
|
||||||
make_profile_plot(logs, "impl-cipher-ver", "cipher", side, record, no_flamegraph=no_flamegraph, machine=machine)
|
make_profile_plot(logs, "impl-cipher-ver", "cipher", side, record, no_flamegraph=no_flamegraph, machine=machine)
|
||||||
make_profile_plot(logs, "impl-cert-ver", "cert", side, record, no_flamegraph=no_flamegraph, machine=machine)
|
make_profile_plot(logs, "impl-cert-ver", "cert", side, record, no_flamegraph=no_flamegraph, machine=machine)
|
||||||
make_profile_plot(logs, "impl-kex-ver", "kex", side, record, no_flamegraph=no_flamegraph, machine=machine)
|
make_profile_plot(logs, "impl-kex-ver", "kex", side, record, no_flamegraph=no_flamegraph, machine=machine)
|
||||||
|
elif cmd == "correl":
|
||||||
|
from scipy import stats
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
make_linear_regression(logs)
|
||||||
|
|
|
||||||
16
profile.py
16
profile.py
|
|
@ -7,27 +7,27 @@ FUNCTIONS = {
|
||||||
|
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::cipher::MessageEncrypter>::encrypt": "encrypt",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::cipher::MessageEncrypter>::encrypt": "encrypt",
|
||||||
|
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::Hkdf>::expander_for_okm": "hkdf",
|
|
||||||
|
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::SecureRandom>::fill": "rand",
|
|
||||||
|
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::SupportedKxGroup>::start": "kx",
|
|
||||||
|
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::hash::Hash>::start": "hash",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::hash::Hash>::start": "hash",
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::hash::Context>::finish": "hash",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::hash::Context>::finish": "hash",
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::hash::Context>::update": "hash",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::hash::Context>::update": "hash",
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::hash::Context>::fork_finish": "hash",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::hash::Context>::fork_finish": "hash",
|
||||||
|
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::Hkdf>::extract_from_secret": "hkdf",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::SupportedKxGroup>::start": "kx",
|
||||||
|
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::ActiveKeyExchange>::complete": "kx",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::ActiveKeyExchange>::complete": "kx",
|
||||||
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::SupportedKxGroup>::start_and_complete": "kx",
|
||||||
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::SupportedKxGroup>::start": "kx",
|
||||||
|
|
||||||
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::SecureRandom>::fill": "rand",
|
||||||
|
|
||||||
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::Hkdf>::expander_for_okm": "hkdf",
|
||||||
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::Hkdf>::extract_from_secret": "hkdf",
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::HkdfExpander>::hash_len": "hkdf",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::HkdfExpander>::hash_len": "hkdf",
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::HkdfExpander>::expand_slice": "hkdf",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::HkdfExpander>::expand_slice": "hkdf",
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::Hkdf>::extract_from_secret": "hkdf",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::Hkdf>::extract_from_secret": "hkdf",
|
||||||
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::Hkdf>::hmac_sign": "hkdf",
|
"<[a-zA-Z0-9_:<>]+ as rustls::crypto::tls13::Hkdf>::hmac_sign": "hkdf",
|
||||||
|
|
||||||
"ring::hkdf::fill_okm": "hkdf",
|
"ring::hkdf::fill_okm": "hkdf",
|
||||||
|
#"ring::hkdf::Salt::extract": "hkdf",
|
||||||
"aws_lc_0_32_2_HKDF": "hkdf",
|
"aws_lc_0_32_2_HKDF": "hkdf",
|
||||||
|
|
||||||
#"rustls_openssl::tls13::<impl rustls::crypto::cipher::Tls13AeadAlgorithm for rustls_openssl::aead::Algorithm>::encrypter": "encrypt",
|
#"rustls_openssl::tls13::<impl rustls::crypto::cipher::Tls13AeadAlgorithm for rustls_openssl::aead::Algorithm>::encrypter": "encrypt",
|
||||||
|
|
|
||||||
2
servers.txt
Normal file
2
servers.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
domain_name,output_rank,date
|
||||||
|
google.com.,1,2025-12-18
|
||||||
Loading…
Add table
Add a link
Reference in a new issue