Skip to content

Commit f50630d

Browse files
committed
chacha: Pass cpu::Features into encrypt.
1 parent a0c2321 commit f50630d

File tree

3 files changed

+45
-28
lines changed

3 files changed

+45
-28
lines changed

src/aead/chacha.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1515

1616
use super::{overlapping, quic::Sample, Nonce};
17+
use crate::cpu;
1718

1819
#[cfg(any(
1920
test,
@@ -51,27 +52,29 @@ impl Key {
5152
&self,
5253
nonce: Nonce,
5354
in_out: &mut [u8; N],
55+
cpu: cpu::Features,
5456
) -> Counter {
5557
assert!(N <= BLOCK_LEN);
5658
let (zero, one) = Counter::zero_one_less_safe(nonce);
57-
self.encrypt(zero, in_out.as_mut().into());
59+
self.encrypt(zero, in_out.as_mut().into(), cpu);
5860
one
5961
}
6062

6163
#[inline]
6264
pub fn new_mask(&self, sample: Sample) -> [u8; 5] {
65+
let cpu = cpu::features(); // TODO: Remove this.
6366
let (ctr, nonce) = sample.split_at(4);
6467
let ctr = u32::from_le_bytes(ctr.try_into().unwrap());
6568
let nonce = Nonce::assume_unique_for_key(nonce.try_into().unwrap());
6669
let ctr = Counter::from_nonce_and_ctr(nonce, ctr);
6770

6871
let mut out: [u8; 5] = [0; 5];
69-
self.encrypt(ctr, out.as_mut().into());
72+
self.encrypt(ctr, out.as_mut().into(), cpu);
7073
out
7174
}
7275

7376
#[inline(always)]
74-
pub fn encrypt(&self, counter: Counter, in_out: Overlapping<'_>) {
77+
pub fn encrypt(&self, counter: Counter, in_out: Overlapping<'_>, _cpu: cpu::Features) {
7578
#[cfg(any(
7679
all(target_arch = "aarch64", target_endian = "little"),
7780
all(target_arch = "arm", target_endian = "little"),
@@ -198,7 +201,9 @@ mod tests {
198201
// Smoketest the fallback implementation.
199202
#[test]
200203
fn chacha20_test_fallback() {
201-
chacha20_test(MAX_ALIGNMENT_AND_OFFSET_SUBSET, fallback::ChaCha20_ctr32);
204+
chacha20_test(MAX_ALIGNMENT_AND_OFFSET_SUBSET, |key, ctr, in_out, _cpu| {
205+
fallback::ChaCha20_ctr32(key, ctr, in_out)
206+
});
202207
}
203208

204209
// Verifies the encryption is successful when done on overlapping buffers.
@@ -210,8 +215,10 @@ mod tests {
210215
// works around that.
211216
fn chacha20_test(
212217
max_alignment_and_offset: (usize, usize),
213-
f: impl for<'k, 'o> Fn(&'k Key, Counter, Overlapping<'o>),
218+
f: impl for<'k, 'o> Fn(&'k Key, Counter, Overlapping<'o>, cpu::Features),
214219
) {
220+
let cpu = cpu::features();
221+
215222
// Reuse a buffer to avoid slowing down the tests with allocations.
216223
let mut buf = vec![0u8; 1300];
217224

@@ -240,6 +247,7 @@ mod tests {
240247
&output[..len],
241248
&mut buf,
242249
max_alignment_and_offset,
250+
cpu,
243251
&f,
244252
);
245253
}
@@ -256,7 +264,8 @@ mod tests {
256264
expected: &[u8],
257265
buf: &mut [u8],
258266
(max_alignment, max_offset): (usize, usize),
259-
f: &impl for<'k, 'o> Fn(&'k Key, Counter, Overlapping<'o>),
267+
cpu: cpu::Features,
268+
f: &impl for<'k, 'o> Fn(&'k Key, Counter, Overlapping<'o>, cpu::Features),
260269
) {
261270
const ARBITRARY: u8 = 123;
262271

@@ -276,7 +285,7 @@ mod tests {
276285
let in_out = Overlapping::new(buf, src)
277286
.map_err(error::erase::<IndexError>)
278287
.unwrap();
279-
f(key, ctr, in_out);
288+
f(key, ctr, in_out, cpu);
280289
assert_eq!(&buf[..input.len()], expected)
281290
}
282291
}

src/aead/chacha20_poly1305/mod.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,13 @@ pub(super) fn seal_fallback(
7171
nonce: Nonce,
7272
aad: Aad<&[u8]>,
7373
in_out: &mut [u8],
74-
cpu_features: cpu::Features,
74+
cpu: cpu::Features,
7575
) -> Result<Tag, InputTooLongError> {
76-
let (counter, poly1305_key) = begin(chacha20_key, nonce, aad, in_out)?;
77-
let mut auth = poly1305::Context::from_key(poly1305_key, cpu_features);
76+
let (counter, poly1305_key) = begin(chacha20_key, nonce, aad, in_out, cpu)?;
77+
let mut auth = poly1305::Context::from_key(poly1305_key, cpu);
7878

7979
poly1305_update_padded_16(&mut auth, aad.as_ref());
80-
chacha20_key.encrypt(counter, in_out.into());
80+
chacha20_key.encrypt(counter, in_out.into(), cpu);
8181
poly1305_update_padded_16(&mut auth, in_out);
8282
Ok(finish(auth, aad.as_ref().len(), in_out.len()))
8383
}
@@ -105,15 +105,15 @@ pub(super) fn open_fallback(
105105
nonce: Nonce,
106106
aad: Aad<&[u8]>,
107107
in_out: Overlapping<'_>,
108-
cpu_features: cpu::Features,
108+
cpu: cpu::Features,
109109
) -> Result<Tag, InputTooLongError> {
110-
let (counter, poly1305_key) = begin(chacha20_key, nonce, aad, in_out.input())?;
111-
let mut auth = poly1305::Context::from_key(poly1305_key, cpu_features);
110+
let (counter, poly1305_key) = begin(chacha20_key, nonce, aad, in_out.input(), cpu)?;
111+
let mut auth = poly1305::Context::from_key(poly1305_key, cpu);
112112

113113
poly1305_update_padded_16(&mut auth, aad.as_ref());
114114
poly1305_update_padded_16(&mut auth, in_out.input());
115115
let in_out_len = in_out.len();
116-
chacha20_key.encrypt(counter, in_out);
116+
chacha20_key.encrypt(counter, in_out, cpu);
117117
Ok(finish(auth, aad.as_ref().len(), in_out_len))
118118
}
119119

@@ -137,11 +137,12 @@ pub(super) fn begin(
137137
nonce: Nonce,
138138
aad: Aad<&[u8]>,
139139
input: &[u8],
140+
cpu: cpu::Features,
140141
) -> Result<(Counter, poly1305::Key), InputTooLongError> {
141142
check_input_lengths(aad, input)?;
142143

143144
let mut key_bytes = [0u8; poly1305::KEY_LEN];
144-
let counter = key.encrypt_single_block_with_ctr_0(nonce, &mut key_bytes);
145+
let counter = key.encrypt_single_block_with_ctr_0(nonce, &mut key_bytes, cpu);
145146
let poly1305_key = poly1305::Key::new(key_bytes);
146147
Ok((counter, poly1305_key))
147148
}

src/aead/chacha20_poly1305_openssh.rs

+19-12
Original file line numberDiff line numberDiff line change
@@ -77,26 +77,28 @@ impl SealingKey {
7777
let (len_in_out, data_and_padding_in_out): (&mut [u8; PACKET_LENGTH_LEN], _) =
7878
slice::split_first_chunk_mut(plaintext_in_ciphertext_out).unwrap();
7979

80-
let cpu_features = cpu::features();
80+
let cpu = cpu::features();
8181
// XXX/TODO(SemVer): Refactor API to return an error.
8282
let (counter, poly_key) = chacha20_poly1305::begin(
8383
&self.key.k_2,
8484
make_nonce(sequence_number),
8585
Aad::from(len_in_out),
8686
data_and_padding_in_out,
87+
cpu,
8788
)
8889
.map_err(error::erase::<InputTooLongError>)
8990
.unwrap();
9091

91-
let _: Counter = self
92-
.key
93-
.k_1
94-
.encrypt_single_block_with_ctr_0(make_nonce(sequence_number), len_in_out);
92+
let _: Counter = self.key.k_1.encrypt_single_block_with_ctr_0(
93+
make_nonce(sequence_number),
94+
len_in_out,
95+
cpu,
96+
);
9597
self.key
9698
.k_2
97-
.encrypt(counter, data_and_padding_in_out.into());
99+
.encrypt(counter, data_and_padding_in_out.into(), cpu);
98100

99-
let Tag(tag) = poly1305::sign(poly_key, plaintext_in_ciphertext_out, cpu_features);
101+
let Tag(tag) = poly1305::sign(poly_key, plaintext_in_ciphertext_out, cpu);
100102
*tag_out = tag;
101103
}
102104
}
@@ -123,11 +125,13 @@ impl OpeningKey {
123125
sequence_number: u32,
124126
encrypted_packet_length: [u8; PACKET_LENGTH_LEN],
125127
) -> [u8; PACKET_LENGTH_LEN] {
128+
let cpu = cpu::features();
126129
let mut packet_length = encrypted_packet_length;
127-
let _: Counter = self
128-
.key
129-
.k_1
130-
.encrypt_single_block_with_ctr_0(make_nonce(sequence_number), &mut packet_length);
130+
let _: Counter = self.key.k_1.encrypt_single_block_with_ctr_0(
131+
make_nonce(sequence_number),
132+
&mut packet_length,
133+
cpu,
134+
);
131135
packet_length
132136
}
133137

@@ -155,6 +159,7 @@ impl OpeningKey {
155159
make_nonce(sequence_number),
156160
Aad::from(packet_length),
157161
after_packet_length,
162+
cpu,
158163
)
159164
.map_err(error::erase::<InputTooLongError>)?;
160165

@@ -167,7 +172,9 @@ impl OpeningKey {
167172
// Won't panic because the length was checked above.
168173
let after_packet_length = &mut ciphertext_in_plaintext_out[PACKET_LENGTH_LEN..];
169174

170-
self.key.k_2.encrypt(counter, after_packet_length.into());
175+
self.key
176+
.k_2
177+
.encrypt(counter, after_packet_length.into(), cpu);
171178

172179
Ok(after_packet_length)
173180
}

0 commit comments

Comments
 (0)