Skip to content

Commit 0646049

Browse files
committed
Fixes
1 parent 9d2c633 commit 0646049

2 files changed

Lines changed: 41 additions & 8 deletions

File tree

src/aead.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ mod recprot {
9999
/// # Safety
100100
///
101101
/// `output`, `tag`, and `input` must be valid for `output_max`, `TAG_LEN`, and `input_len`
102-
/// bytes respectively.
102+
/// bytes respectively. `output` and `input` may fully overlap (in-place operation); `tag`
103+
/// must not overlap with the `output` region.
103104
#[expect(
104105
clippy::too_many_arguments,
105106
reason = "Thin wrapper over a 14-argument C function."
@@ -121,7 +122,7 @@ mod recprot {
121122
PK11_AEADOp(
122123
**ctx,
123124
CK_GENERATOR_FUNCTION::from(CKG_NO_GENERATE),
124-
0,
125+
super::c_int_len(super::NONCE_LEN - super::COUNTER_LEN)?,
125126
nonce.as_mut_ptr(),
126127
super::c_int_len(super::NONCE_LEN)?,
127128
aad.as_ptr(),
@@ -208,7 +209,12 @@ mod recprot {
208209
input: &[u8],
209210
output: &'a mut [u8],
210211
) -> Res<&'a [u8]> {
211-
if output.len() < input.len() + super::TAG_LEN {
212+
if output.len()
213+
< input
214+
.len()
215+
.checked_add(super::TAG_LEN)
216+
.ok_or(Error::IntegerOverflow)?
217+
{
212218
return Err(Error::from(SEC_ERROR_BAD_DATA));
213219
}
214220
let out_len = unsafe {
@@ -225,7 +231,7 @@ mod recprot {
225231
)
226232
}?;
227233
debug_assert_eq!(out_len, input.len());
228-
Ok(&output[..input.len() + super::TAG_LEN])
234+
Ok(&output[..out_len + super::TAG_LEN])
229235
}
230236

231237
/// Encrypt plaintext in place with associated data.
@@ -275,15 +281,17 @@ mod recprot {
275281
if output.len() < ct_len {
276282
return Err(Error::from(SEC_ERROR_BAD_DATA));
277283
}
284+
let mut tag = [0u8; super::TAG_LEN];
285+
tag.copy_from_slice(&input[ct_len..]);
278286
let out_len = unsafe {
279287
aead_op(
280288
&self.ctx_decrypt,
281289
&self.nonce_base,
282290
count,
283291
aad,
284292
output.as_mut_ptr(),
285-
ct_len,
286-
input.as_ptr().add(ct_len).cast_mut(),
293+
output.len(),
294+
tag.as_mut_ptr(),
287295
input.as_ptr(),
288296
ct_len,
289297
)
@@ -309,7 +317,7 @@ mod recprot {
309317
count,
310318
aad,
311319
data_ptr,
312-
ct_len,
320+
data.len(),
313321
data_ptr.add(ct_len),
314322
data_ptr.cast_const(),
315323
ct_len,

tests/aead.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99

1010
use nss_rs::{
1111
RecordProtection,
12-
constants::{Cipher, TLS_AES_128_GCM_SHA256, TLS_VERSION_1_3},
12+
constants::{
13+
Cipher, TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256,
14+
TLS_VERSION_1_3,
15+
},
1316
hkdf,
1417
};
1518
use test_fixture::fixture_init;
@@ -149,3 +152,25 @@ fn encrypt_decrypt_in_place() {
149152
assert_eq!(decrypted_len, plaintext.len());
150153
assert_eq!(&buffer[..decrypted_len], plaintext);
151154
}
155+
156+
fn roundtrip(cipher: Cipher) {
157+
let aead = make_aead(cipher);
158+
let mut buf = &mut [0u8; 1024][..];
159+
160+
let ct = aead.encrypt(42, AAD, PLAINTEXT, &mut buf).expect("encrypt");
161+
let pt_buf = &mut [0u8; 1024][..];
162+
let pt = aead
163+
.decrypt(42, AAD, ct, &mut pt_buf[..ct.len()])
164+
.expect("decrypt");
165+
assert_eq!(pt, PLAINTEXT);
166+
}
167+
168+
#[test]
169+
fn roundtrip_aes256() {
170+
roundtrip(TLS_AES_256_GCM_SHA384);
171+
}
172+
173+
#[test]
174+
fn roundtrip_chacha20() {
175+
roundtrip(TLS_CHACHA20_POLY1305_SHA256);
176+
}

0 commit comments

Comments
 (0)