Skip to content

Commit f1e6e0d

Browse files
jmayclinmaddeleinegoatgoose
authored
fix(benches): reuse config for handshakes (#5319)
Co-authored-by: maddeleine <59030281+maddeleine@users.noreply.github.com> Co-authored-by: Sam Clark <3758302+goatgoose@users.noreply.github.com>
1 parent 8b0693a commit f1e6e0d

File tree

4 files changed

+29
-16
lines changed

4 files changed

+29
-16
lines changed

bindings/rust/standard/bench/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ rustls-pemfile = { version = "2" }
1414
openssl = { version = "0.10", features = ["vendored"] }
1515

1616
[dev-dependencies]
17-
criterion = "0.5"
17+
criterion = "0.6"
1818
pprof = { version = "0.14", features = ["criterion", "flamegraph"] }
1919
# env_logger and log are used to enable logging for rustls, which can help with
2020
# debugging interop failures

bindings/rust/standard/bench/benches/handshake.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,11 @@
33

44
use bench::{
55
harness::TlsBenchConfig, CipherSuite, CryptoConfig, HandshakeType, KXGroup, Mode,
6-
OpenSslConnection, RustlsConnection, S2NConnection, SigType, TlsConnPair, TlsConnection,
7-
PROFILER_FREQUENCY,
6+
OpenSslConnection, RustlsConnection, S2NConnection, SigType, TlsConnPair, TlsConnection
87
};
98
use criterion::{
109
criterion_group, criterion_main, measurement::WallTime, BatchSize, BenchmarkGroup, Criterion,
1110
};
12-
use pprof::criterion::{Output, PProfProfiler};
1311
use strum::IntoEnumIterator;
1412

1513
fn bench_handshake_for_library<T>(
@@ -22,20 +20,34 @@ fn bench_handshake_for_library<T>(
2220
T::Config: TlsBenchConfig,
2321
{
2422
let crypto_config = CryptoConfig::new(CipherSuite::default(), kx_group, sig_type);
23+
let client_config = &T::Config::make_config(Mode::Client, crypto_config, handshake_type).unwrap();
24+
let server_config = &T::Config::make_config(Mode::Server, crypto_config, handshake_type).unwrap();
2525

2626
// generate all harnesses (TlsConnPair structs) beforehand so that benchmarks
2727
// only include negotiation and not config/connection initialization
2828
bench_group.bench_function(T::name(), |b| {
2929
b.iter_batched_ref(
30-
|| -> TlsConnPair<T, T> { TlsConnPair::new_bench_pair(crypto_config, handshake_type).unwrap() },
30+
|| -> TlsConnPair<T, T> {
31+
if handshake_type == HandshakeType::Resumption {
32+
// generate a session ticket to store on the config
33+
let mut pair = TlsConnPair::<T, T>::from_configs(&client_config, &server_config);
34+
pair.handshake().unwrap();
35+
pair.round_trip_transfer(&mut [0]).unwrap();
36+
}
37+
TlsConnPair::from_configs(client_config, server_config)
38+
},
3139
|conn_pair| {
3240
conn_pair.handshake().unwrap();
3341
match handshake_type {
3442
HandshakeType::ServerAuth | HandshakeType::MutualAuth => assert!(!conn_pair.server.resumed_connection()),
3543
HandshakeType::Resumption => assert!(conn_pair.server.resumed_connection()),
3644
}
3745
},
38-
BatchSize::SmallInput,
46+
// Use "PerIteration" benchmarking, because of the way that session
47+
// ticket setup interacts with shared configs.
48+
// > In testing, the maximum measurement overhead from benchmarking
49+
// > with PerIteration is on the order of 350 nanoseconds
50+
BatchSize::PerIteration,
3951
)
4052
});
4153
}
@@ -98,9 +110,6 @@ pub fn bench_handshake_sig_types(c: &mut Criterion) {
98110
}
99111

100112
criterion_group! {
101-
name = benches;
102-
// profile 100 samples/sec
103-
config = Criterion::default().with_profiler(PProfProfiler::new(PROFILER_FREQUENCY, Output::Flamegraph(None)));
104-
targets = bench_handshake_types, bench_handshake_kx_groups, bench_handshake_sig_types
113+
benches, bench_handshake_types, bench_handshake_kx_groups, bench_handshake_sig_types
105114
}
106115
criterion_main!(benches);

bindings/rust/standard/bench/benches/throughput.rs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,5 @@ pub fn bench_throughput_cipher_suites(c: &mut Criterion) {
6868
}
6969
}
7070

71-
criterion_group! {
72-
name = benches;
73-
// profile 100 samples/sec
74-
config = Criterion::default().with_profiler(PProfProfiler::new(PROFILER_FREQUENCY, Output::Flamegraph(None)));
75-
targets = bench_throughput_cipher_suites
76-
}
71+
criterion_group! {benches, bench_throughput_cipher_suites}
7772
criterion_main!(benches);

crypto/s2n_pkey.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,15 @@ int s2n_pkey_match(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_k
161161
POSIX_GUARD_RESULT(s2n_pkey_size(priv_key, &size));
162162
POSIX_GUARD(s2n_alloc(&signature, size));
163163

164+
/* Note: The Libcrypto RSA EVP_PKEY will cache certain computations used for
165+
* RSA signing.
166+
*
167+
* This means that the first RSA sign with an EVP_PKEY is ~300 us slower
168+
* than subsequent sign operations. The effect is much smaller for ECDSA signatures.
169+
*
170+
* If this pkey_sign operation is moved out of config creation, then the
171+
* 300 us penalty will be paid by the first handshake done on the config.
172+
*/
164173
POSIX_GUARD(s2n_pkey_sign(priv_key, check_alg, &state_in, &signature));
165174
POSIX_ENSURE(s2n_pkey_verify(pub_key, check_alg, &state_out, &signature) == S2N_SUCCESS,
166175
S2N_ERR_KEY_MISMATCH);

0 commit comments

Comments
 (0)