Skip to content

Commit 0159744

Browse files
committed
Expand API; improve test structure
1 parent 505ef99 commit 0159744

File tree

1 file changed

+114
-51
lines changed

1 file changed

+114
-51
lines changed

aws-lc-rs/src/cipher/stream.rs

Lines changed: 114 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,27 @@ impl StreamingEncryptingKey {
5858
}
5959

6060
pub fn cbc_pkcs7(key: UnboundCipherKey) -> Result<Self, Unspecified> {
61-
let mode = OperatingMode::CBC;
62-
let context = key.algorithm().new_encryption_context(mode)?;
63-
StreamingEncryptingKey::new(key, mode, context)
61+
let context = key.algorithm().new_encryption_context(OperatingMode::CBC)?;
62+
Self::less_safe_cbc_pkcs7(key, context)
63+
}
64+
65+
pub fn less_safe_cbc_pkcs7(
66+
key: UnboundCipherKey,
67+
context: EncryptionContext,
68+
) -> Result<Self, Unspecified> {
69+
StreamingEncryptingKey::new(key, OperatingMode::CBC, context)
6470
}
6571

6672
pub fn ctr(key: UnboundCipherKey) -> Result<Self, Unspecified> {
67-
let mode = OperatingMode::CTR;
68-
let context = key.algorithm().new_encryption_context(mode)?;
69-
StreamingEncryptingKey::new(key, mode, context)
73+
let context = key.algorithm().new_encryption_context(OperatingMode::CTR)?;
74+
Self::less_safe_ctr(key, context)
75+
}
76+
77+
pub fn less_safe_ctr(
78+
key: UnboundCipherKey,
79+
context: EncryptionContext,
80+
) -> Result<Self, Unspecified> {
81+
StreamingEncryptingKey::new(key, OperatingMode::CTR, context)
7082
}
7183

7284
/// Returns the cipher operating mode.
@@ -81,7 +93,7 @@ impl StreamingEncryptingKey {
8193
}
8294

8395
pub fn update<'a>(&self, input: &[u8], output: &'a mut [u8]) -> Result<usize, Unspecified> {
84-
if output.len() < (input.len() + self.algorithm.block_len - 1) {
96+
if output.len() < (input.len() + self.algorithm.block_len) {
8597
return Err(Unspecified);
8698
}
8799

@@ -215,11 +227,86 @@ impl StreamingDecryptingKey {
215227
#[cfg(test)]
216228
mod tests {
217229
use crate::cipher::stream::{StreamingDecryptingKey, StreamingEncryptingKey};
218-
use crate::cipher::{Algorithm, UnboundCipherKey, AES_256, AES_256_KEY_LEN};
230+
use crate::cipher::{Algorithm, DecryptionContext, UnboundCipherKey, AES_256, AES_256_KEY_LEN};
219231
use crate::rand::{SecureRandom, SystemRandom};
220232
use paste::*;
221233

222-
macro_rules! helper_stream_step_test {
234+
fn step_encrypt(
235+
encrypting_key: StreamingEncryptingKey,
236+
plaintext: &[u8],
237+
step: usize,
238+
) -> (Box<[u8]>, DecryptionContext) {
239+
let alg = encrypting_key.algorithm();
240+
let mode = encrypting_key.mode();
241+
let n = plaintext.len();
242+
let mut ciphertext = vec![0u8; n + alg.block_len()];
243+
244+
let mut in_idx: usize = 0;
245+
let mut out_idx: usize = 0;
246+
loop {
247+
let mut in_end = in_idx + step;
248+
if in_end > n {
249+
in_end = n;
250+
}
251+
let out_end = out_idx + (in_end - in_idx) + alg.block_len();
252+
let outlen = encrypting_key
253+
.update(
254+
&plaintext[in_idx..in_end],
255+
&mut ciphertext[out_idx..out_end],
256+
)
257+
.unwrap();
258+
in_idx += step;
259+
out_idx += outlen;
260+
if in_idx >= n {
261+
break;
262+
}
263+
}
264+
let out_end = out_idx + alg.block_len();
265+
let (decrypt_iv, outlen) = encrypting_key
266+
.finish(&mut ciphertext[out_idx..out_end])
267+
.unwrap();
268+
269+
ciphertext.truncate(out_idx + outlen);
270+
(ciphertext.into_boxed_slice(), decrypt_iv)
271+
}
272+
273+
fn step_decrypt(
274+
decrypting_key: StreamingDecryptingKey,
275+
ciphertext: &[u8],
276+
step: usize,
277+
) -> Box<[u8]> {
278+
let alg = decrypting_key.algorithm();
279+
let n = ciphertext.len();
280+
let mut output = vec![0u8; n + alg.block_len()];
281+
282+
let mut in_idx: usize = 0;
283+
let mut out_idx: usize = 0;
284+
loop {
285+
let mut in_end = in_idx + step;
286+
if in_end > n {
287+
in_end = n;
288+
}
289+
let out_end = out_idx + (in_end - in_idx) + alg.block_len();
290+
let outlen = decrypting_key
291+
.update(&ciphertext[in_idx..in_end], &mut output[out_idx..out_end])
292+
.unwrap();
293+
in_idx += step;
294+
out_idx += outlen;
295+
if in_idx >= n {
296+
break;
297+
}
298+
}
299+
let out_end = out_idx + alg.block_len();
300+
let outlen = decrypting_key
301+
.finish(&mut output[out_idx..out_end])
302+
.unwrap();
303+
304+
output.truncate(out_idx + outlen);
305+
306+
output.into_boxed_slice()
307+
}
308+
309+
macro_rules! helper_stream_step_encrypt_test {
223310
($mode:ident) => {
224311
paste! {
225312
fn [<helper_test_ $mode _stream_encrypt_step_n_bytes>](
@@ -228,82 +315,58 @@ mod tests {
228315
n: usize,
229316
step: usize,
230317
) {
231-
let mut input: Vec<u8> = Vec::with_capacity(n);
232-
for i in 0..n {
233-
let byte: u8 = (i % 256).try_into().unwrap();
234-
input.push(byte);
235-
}
318+
let mut input = vec![0u8; n];
319+
let random = SystemRandom::new();
320+
random.fill(&mut input).unwrap();
236321

237322
let cipher_key = UnboundCipherKey::new(alg, key).unwrap();
238323
let encrypting_key = StreamingEncryptingKey::$mode(cipher_key).unwrap();
239324

240-
let mut ciphertext = vec![0u8; n + alg.block_len()];
241-
242-
let mut in_idx: usize = 0;
243-
let mut out_idx: usize = 0;
244-
loop {
245-
let mut in_end = in_idx + step;
246-
if in_end > n {
247-
in_end = n;
248-
}
249-
let out_end = out_idx + (in_end - in_idx) + alg.block_len() - 1;
250-
let outlen = encrypting_key
251-
.update(&input[in_idx..in_end], &mut ciphertext[out_idx..out_end])
252-
.unwrap();
253-
in_idx += step;
254-
out_idx += outlen;
255-
if in_idx >= n {
256-
break;
257-
}
258-
}
259-
let out_end = out_idx + alg.block_len();
260-
let (decrypt_iv, outlen) = encrypting_key
261-
.finish(&mut ciphertext[out_idx..out_end])
262-
.unwrap();
263-
eprintln!("{} ciphertext length: n: {}, step: {}, cipherlength: {}", stringify!($mode), n, step, out_idx + outlen);
264-
ciphertext.truncate(out_idx + outlen);
325+
let (ciphertext, decrypt_iv) = step_encrypt(encrypting_key, &input, step);
265326

266327
let cipher_key2 = UnboundCipherKey::new(alg, key).unwrap();
267328
let decrypting_key = StreamingDecryptingKey::$mode(cipher_key2, decrypt_iv).unwrap();
268329

269-
let mut plaintext = vec![0u8; n + 2*alg.block_len()];
270-
let outlen = decrypting_key
271-
.update(ciphertext.as_slice(), plaintext.as_mut_slice())
272-
.unwrap();
273-
let outlen = outlen + decrypting_key.finish(&mut plaintext[outlen..n]).unwrap();
330+
let plaintext = step_decrypt(decrypting_key, &ciphertext, step);
274331

275-
assert_eq!(input.as_slice(), &plaintext[0..outlen]);
332+
assert_eq!(input.as_slice(), &*plaintext);
276333
}
277334
}
278335

279336
};
280337
}
281338

282-
helper_stream_step_test!(cbc_pkcs7);
283-
helper_stream_step_test!(ctr);
339+
helper_stream_step_encrypt_test!(cbc_pkcs7);
340+
helper_stream_step_encrypt_test!(ctr);
284341

285342
#[test]
286-
fn test_cbc() {
343+
fn test_step_cbc() {
287344
let random = SystemRandom::new();
288345
let mut key = [0u8; AES_256_KEY_LEN];
289346
random.fill(&mut key).unwrap();
290347

291348
for i in 13..=21 {
292-
for j in 125..=131 {
349+
for j in 124..=131 {
293350
let _ = helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes(&key, &AES_256, j, i);
294351
}
352+
for j in 124..=131 {
353+
let _ = helper_test_cbc_pkcs7_stream_encrypt_step_n_bytes(&key, &AES_256, j, j - i);
354+
}
295355
}
296356
}
297357

298358
#[test]
299-
fn test_ctr() {
359+
fn test_step_ctr() {
300360
let random = SystemRandom::new();
301361
let mut key = [0u8; AES_256_KEY_LEN];
302362
random.fill(&mut key).unwrap();
303363
for i in 13..=21 {
304-
for j in 125..=131 {
364+
for j in 124..=131 {
305365
let _ = helper_test_ctr_stream_encrypt_step_n_bytes(&key, &AES_256, j, i);
306366
}
367+
for j in 124..=131 {
368+
let _ = helper_test_ctr_stream_encrypt_step_n_bytes(&key, &AES_256, j, j - i);
369+
}
307370
}
308371
}
309372
}

0 commit comments

Comments
 (0)