1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #![allow(missing_docs, clippy::expect_used, clippy::unwrap_used)]
16
17 use criterion::{black_box, criterion_group, criterion_main, Criterion, Throughput};
18 use rand::{Rng, SeedableRng};
19
20 use crypto_provider::CryptoProvider;
21 use crypto_provider_default::CryptoProviderImpl;
22 use ukey2_connections::{
23 D2DConnectionContextV1, D2DHandshakeContext, InitiatorD2DHandshakeContext,
24 ServerD2DHandshakeContext,
25 };
26 use ukey2_rs::{HandshakeImplementation, NextProtocol};
27
run_handshake_with_rng<C, R>( mut rng: R, next_protocols: Vec<NextProtocol>, ) -> (D2DConnectionContextV1<R>, D2DConnectionContextV1<R>) where C: CryptoProvider, R: rand::RngCore + rand::CryptoRng + rand::SeedableRng + Send,28 fn run_handshake_with_rng<C, R>(
29 mut rng: R,
30 next_protocols: Vec<NextProtocol>,
31 ) -> (D2DConnectionContextV1<R>, D2DConnectionContextV1<R>)
32 where
33 C: CryptoProvider,
34 R: rand::RngCore + rand::CryptoRng + rand::SeedableRng + Send,
35 {
36 let mut initiator_ctx = InitiatorD2DHandshakeContext::<C, R>::new_impl(
37 HandshakeImplementation::Spec,
38 R::from_rng(&mut rng).unwrap(),
39 next_protocols.clone(),
40 );
41 let mut server_ctx = ServerD2DHandshakeContext::<C, R>::new_impl(
42 HandshakeImplementation::Spec,
43 R::from_rng(&mut rng).unwrap(),
44 &next_protocols,
45 );
46 server_ctx
47 .handle_handshake_message(
48 initiator_ctx.get_next_handshake_message().expect("No message").as_slice(),
49 )
50 .expect("Failed to handle message");
51 initiator_ctx
52 .handle_handshake_message(
53 server_ctx.get_next_handshake_message().expect("No message").as_slice(),
54 )
55 .expect("Failed to handle message");
56 server_ctx
57 .handle_handshake_message(
58 initiator_ctx.get_next_handshake_message().expect("No message").as_slice(),
59 )
60 .expect("Failed to handle message");
61 assert!(initiator_ctx.is_handshake_complete());
62 assert!(server_ctx.is_handshake_complete());
63 (initiator_ctx.to_connection_context().unwrap(), server_ctx.to_connection_context().unwrap())
64 }
65
cbc_criterion_benchmark(c: &mut Criterion)66 fn cbc_criterion_benchmark(c: &mut Criterion) {
67 let kib = 1024;
68 let mut group = c.benchmark_group("throughput");
69 let mut plaintext = Vec::new();
70 let (mut initiator_ctx, mut server_ctx) = run_handshake_with_rng::<CryptoProviderImpl, _>(
71 rand::rngs::StdRng::from_entropy(),
72 vec![NextProtocol::Aes256CbcHmacSha256],
73 );
74 for len in [10 * kib, 1024 * kib] {
75 let _ = group.throughput(Throughput::Bytes(len as u64));
76 plaintext.resize(len, 0);
77 rand::thread_rng().fill(&mut plaintext[..]);
78 let _ = group.bench_function(
79 format!("AES-CBC-256_HMAC-SHA256 UKEY2 encrypt/decrypt {}KiB", len / kib),
80 |b| {
81 b.iter(|| {
82 let msg = initiator_ctx
83 .encode_message_to_peer::<CryptoProviderImpl, &[u8]>(&plaintext, None);
84 black_box(
85 server_ctx
86 .decode_message_from_peer::<CryptoProviderImpl, &[u8]>(&msg, None),
87 )
88 })
89 },
90 );
91 }
92 }
93
gcm_criterion_benchmark(c: &mut Criterion)94 fn gcm_criterion_benchmark(c: &mut Criterion) {
95 let kib = 1024;
96 let mut group = c.benchmark_group("throughput");
97 let mut plaintext = Vec::new();
98 let (mut initiator_ctx, mut server_ctx) = run_handshake_with_rng::<CryptoProviderImpl, _>(
99 rand::rngs::StdRng::from_entropy(),
100 vec![NextProtocol::Aes256GcmSiv],
101 );
102 for len in [10 * kib, 1024 * kib] {
103 let _ = group.throughput(Throughput::Bytes(len as u64));
104 plaintext.resize(len, 0);
105 rand::thread_rng().fill(&mut plaintext[..]);
106 let _ = group.bench_function(
107 format!("AES-GCM-SIV UKEY2 encrypt/decrypt {}KiB", len / kib),
108 |b| {
109 b.iter(|| {
110 let msg = initiator_ctx
111 .encode_message_to_peer::<CryptoProviderImpl, &[u8]>(&plaintext, None);
112 black_box(
113 server_ctx
114 .decode_message_from_peer::<CryptoProviderImpl, &[u8]>(&msg, None),
115 )
116 })
117 },
118 );
119 }
120 }
121
122 criterion_group!(benches, cbc_criterion_benchmark, gcm_criterion_benchmark);
123 criterion_main!(benches);
124