Skip to content

Commit c30f142

Browse files
committed
Stream cipher API
1 parent 00a2ad3 commit c30f142

File tree

3 files changed

+626
-3
lines changed

3 files changed

+626
-3
lines changed

aws-lc-rs/src/cipher.rs

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,53 @@
8383
//! # }
8484
//! ```
8585
//!
86+
//! ### AES-128 CBC Streaming Cipher
87+
//!
88+
//! ```rust
89+
//! # use std::error::Error;
90+
//! #
91+
//! # fn main() -> Result<(), Box<dyn Error>> {
92+
//! use aws_lc_rs::cipher::{StreamingDecryptingKey, StreamingEncryptingKey, UnboundCipherKey, AES_128};
93+
//!
94+
//! let original_message = "This is a secret message!".as_bytes();
95+
//!
96+
//! let key_bytes: &[u8] = &[
97+
//! 0xff, 0x0b, 0xe5, 0x84, 0x64, 0x0b, 0x00, 0xc8, 0x90, 0x7a, 0x4b, 0xbf, 0x82, 0x7c, 0xb6,
98+
//! 0xd1,
99+
//! ];
100+
//!
101+
//! // Encrypt
102+
//! let mut ciphertext_buffer = vec![0u8; original_message.len() + AES_128.block_len()];
103+
//! let ciphertext_slice = ciphertext_buffer.as_mut_slice();
104+
//!
105+
//! let key = UnboundCipherKey::new(&AES_128, key_bytes)?;
106+
//! let mut encrypting_key = StreamingEncryptingKey::cbc_pkcs7(key)?;
107+
//! let written_slice = encrypting_key.update(original_message, ciphertext_slice)?;
108+
//! let written_len = written_slice.len();
109+
//! let remaining_slice = &mut ciphertext_slice[written_len..];
110+
//! let (context, written_slice) = encrypting_key.finish(remaining_slice)?;
111+
//! let ciphertext_len = written_len + written_slice.len();
112+
//! let ciphertext = &ciphertext_slice[0..ciphertext_len];
113+
//!
114+
//! // Decrypt
115+
//! let mut plaintext_buffer = vec![0u8; ciphertext_len + AES_128.block_len()];
116+
//! let plaintext_slice = plaintext_buffer.as_mut_slice();
117+
//!
118+
//! let key = UnboundCipherKey::new(&AES_128, key_bytes)?;
119+
//! let mut decrypting_key = StreamingDecryptingKey::cbc_pkcs7(key, context)?;
120+
//! let written_slice = decrypting_key.update(ciphertext, plaintext_slice)?;
121+
//! let written_len = written_slice.len();
122+
//! let remaining_slice = &mut plaintext_slice[written_len..];
123+
//! let written_slice = decrypting_key.finish(remaining_slice)?;
124+
//! let plaintext_len = written_len + written_slice.len();
125+
//! let plaintext = &plaintext_slice[0..plaintext_len];
126+
//!
127+
//! assert_eq!(original_message, plaintext);
128+
//! #
129+
//! # Ok(())
130+
//! # }
131+
//! ```
132+
//!
86133
//! ## Constructing a `DecryptionContext` for decryption.
87134
//!
88135
//! ```rust
@@ -142,8 +189,10 @@ pub(crate) mod block;
142189
pub(crate) mod chacha;
143190
pub(crate) mod key;
144191
mod padded;
192+
mod streaming;
145193

146194
pub use padded::{PaddedBlockDecryptingKey, PaddedBlockEncryptingKey};
195+
pub use streaming::{StreamingDecryptingKey, StreamingEncryptingKey};
147196

148197
use crate::buffer::Buffer;
149198
use crate::error::Unspecified;
@@ -280,7 +329,9 @@ impl Algorithm {
280329
&self.id
281330
}
282331

283-
const fn block_len(&self) -> usize {
332+
/// The block length of this cipher algorithm.
333+
#[must_use]
334+
pub const fn block_len(&self) -> usize {
284335
self.block_len
285336
}
286337

@@ -905,4 +956,47 @@ mod tests {
905956
"eca7285d19f3c20e295378460e8729",
906957
"b5098e5e788de6ac2f2098eb2fc6f8"
907958
);
959+
960+
#[test]
961+
fn streaming_cipher() {
962+
use crate::cipher::{
963+
StreamingDecryptingKey, StreamingEncryptingKey, UnboundCipherKey, AES_128,
964+
};
965+
966+
let original_message = "This is a secret message!".as_bytes();
967+
968+
let key_bytes: &[u8] = &[
969+
0xff, 0x0b, 0xe5, 0x84, 0x64, 0x0b, 0x00, 0xc8, 0x90, 0x7a, 0x4b, 0xbf, 0x82, 0x7c,
970+
0xb6, 0xd1,
971+
];
972+
973+
// Encrypt
974+
let mut ciphertext_buffer = vec![0u8; original_message.len() + AES_128.block_len()];
975+
let ciphertext_slice = ciphertext_buffer.as_mut_slice();
976+
977+
let key = UnboundCipherKey::new(&AES_128, key_bytes).unwrap();
978+
let mut encrypting_key = StreamingEncryptingKey::cbc_pkcs7(key).unwrap();
979+
let written_slice = encrypting_key
980+
.update(original_message, ciphertext_slice)
981+
.unwrap();
982+
let written_len = written_slice.len();
983+
let remaining_slice = &mut ciphertext_slice[written_len..];
984+
let (context, written_slice) = encrypting_key.finish(remaining_slice).unwrap();
985+
let ciphertext_len = written_len + written_slice.len();
986+
let ciphertext = &ciphertext_slice[0..ciphertext_len];
987+
988+
// Decrypt
989+
let mut plaintext_buffer = vec![0u8; ciphertext_len + AES_128.block_len()];
990+
let plaintext_slice = plaintext_buffer.as_mut_slice();
991+
let key = UnboundCipherKey::new(&AES_128, key_bytes).unwrap();
992+
let mut decrypting_key = StreamingDecryptingKey::cbc_pkcs7(key, context).unwrap();
993+
let written_slice = decrypting_key.update(ciphertext, plaintext_slice).unwrap();
994+
let written_len = written_slice.len();
995+
let remaining_slice = &mut plaintext_slice[written_len..];
996+
let written_slice = decrypting_key.finish(remaining_slice).unwrap();
997+
let plaintext_len = written_len + written_slice.len();
998+
let plaintext = &plaintext_slice[0..plaintext_len];
999+
1000+
assert_eq!(original_message, plaintext);
1001+
}
9081002
}

0 commit comments

Comments
 (0)