summaryrefslogtreecommitdiffstats
path: root/vendor/openssl/src/cipher_ctx.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-18 02:49:50 +0000
commit9835e2ae736235810b4ea1c162ca5e65c547e770 (patch)
tree3fcebf40ed70e581d776a8a4c65923e8ec20e026 /vendor/openssl/src/cipher_ctx.rs
parentReleasing progress-linux version 1.70.0+dfsg2-1~progress7.99u1. (diff)
downloadrustc-9835e2ae736235810b4ea1c162ca5e65c547e770.tar.xz
rustc-9835e2ae736235810b4ea1c162ca5e65c547e770.zip
Merging upstream version 1.71.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/openssl/src/cipher_ctx.rs')
-rw-r--r--vendor/openssl/src/cipher_ctx.rs77
1 files changed, 77 insertions, 0 deletions
diff --git a/vendor/openssl/src/cipher_ctx.rs b/vendor/openssl/src/cipher_ctx.rs
index 211c58ba2..216c09e5b 100644
--- a/vendor/openssl/src/cipher_ctx.rs
+++ b/vendor/openssl/src/cipher_ctx.rs
@@ -591,6 +591,50 @@ impl CipherCtxRef {
Ok(len)
}
+ /// Like [`Self::cipher_update`] except that it writes output into the
+ /// `data` buffer. The `inlen` parameter specifies the number of bytes in
+ /// `data` that are considered the input. For streaming ciphers, the size of
+ /// `data` must be at least the input size. Otherwise, it must be at least
+ /// an additional block size larger.
+ ///
+ /// Note: Use [`Self::cipher_update`] with no output argument to write AAD.
+ ///
+ /// # Panics
+ ///
+ /// This function panics if the input size cannot be represented as `int` or
+ /// exceeds the buffer size, or if the output buffer does not contain enough
+ /// additional space.
+ #[corresponds(EVP_CipherUpdate)]
+ pub fn cipher_update_inplace(
+ &mut self,
+ data: &mut [u8],
+ inlen: usize,
+ ) -> Result<usize, ErrorStack> {
+ assert!(inlen <= data.len(), "Input size may not exceed buffer size");
+ let block_size = self.block_size();
+ if block_size != 1 {
+ assert!(
+ data.len() >= inlen + block_size,
+ "Output buffer size must be at least {} bytes.",
+ inlen + block_size
+ );
+ }
+
+ let inlen = c_int::try_from(inlen).unwrap();
+ let mut outlen = 0;
+ unsafe {
+ cvt(ffi::EVP_CipherUpdate(
+ self.as_ptr(),
+ data.as_mut_ptr(),
+ &mut outlen,
+ data.as_ptr(),
+ inlen,
+ ))
+ }?;
+
+ Ok(outlen as usize)
+ }
+
/// Finalizes the encryption or decryption process.
///
/// Any remaining data will be written to the output buffer.
@@ -778,6 +822,26 @@ mod test {
ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
+ // encrypt again, but use in-place encryption this time
+ // First reset the IV
+ ctx.encrypt_init(None, None, Some(&iv)).unwrap();
+ ctx.set_padding(false);
+ let mut data_inplace: [u8; 32] = [1; 32];
+ let outlen = ctx
+ .cipher_update_inplace(&mut data_inplace[0..15], 15)
+ .unwrap();
+ assert_eq!(15, outlen);
+
+ let outlen = ctx
+ .cipher_update_inplace(&mut data_inplace[15..32], 17)
+ .unwrap();
+ assert_eq!(17, outlen);
+
+ ctx.cipher_final(&mut [0u8; 0]).unwrap();
+
+ // Check that the resulting data is encrypted in the same manner
+ assert_eq!(data_inplace.as_slice(), output.as_slice());
+
// try to decrypt
ctx.decrypt_init(Some(cipher), Some(&key), Some(&iv))
.unwrap();
@@ -800,6 +864,19 @@ mod test {
ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
// check if the decrypted blocks are the same as input (all ones)
assert_eq!(output_decrypted, vec![1; 32]);
+
+ // decrypt again, but now the output in-place
+ ctx.decrypt_init(None, None, Some(&iv)).unwrap();
+ ctx.set_padding(false);
+
+ let outlen = ctx.cipher_update_inplace(&mut output[0..15], 15).unwrap();
+ assert_eq!(15, outlen);
+
+ let outlen = ctx.cipher_update_inplace(&mut output[15..], 17).unwrap();
+ assert_eq!(17, outlen);
+
+ ctx.cipher_final_vec(&mut vec![0; 0]).unwrap();
+ assert_eq!(output_decrypted, output);
}
#[test]