diff options
Diffstat (limited to 'vendor/openssl/src/cipher_ctx.rs')
-rw-r--r-- | vendor/openssl/src/cipher_ctx.rs | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/vendor/openssl/src/cipher_ctx.rs b/vendor/openssl/src/cipher_ctx.rs index 216c09e5b..f9031d297 100644 --- a/vendor/openssl/src/cipher_ctx.rs +++ b/vendor/openssl/src/cipher_ctx.rs @@ -55,6 +55,8 @@ use crate::error::ErrorStack; #[cfg(not(boringssl))] use crate::pkey::{HasPrivate, HasPublic, PKey, PKeyRef}; use crate::{cvt, cvt_p}; +#[cfg(ossl102)] +use bitflags::bitflags; use cfg_if::cfg_if; use foreign_types::{ForeignType, ForeignTypeRef}; use libc::{c_int, c_uchar}; @@ -80,6 +82,15 @@ foreign_type_and_impl_send_sync! { pub struct CipherCtxRef; } +#[cfg(ossl102)] +bitflags! { + /// Flags for `EVP_CIPHER_CTX`. + pub struct CipherCtxFlags : c_int { + /// The flag used to opt into AES key wrap ciphers. + const FLAG_WRAP_ALLOW = ffi::EVP_CIPHER_CTX_FLAG_WRAP_ALLOW; + } +} + impl CipherCtx { /// Creates a new context. #[corresponds(EVP_CIPHER_CTX_new)] @@ -94,6 +105,14 @@ impl CipherCtx { } impl CipherCtxRef { + #[corresponds(EVP_CIPHER_CTX_copy)] + pub fn copy(&mut self, src: &CipherCtxRef) -> Result<(), ErrorStack> { + unsafe { + cvt(ffi::EVP_CIPHER_CTX_copy(self.as_ptr(), src.as_ptr()))?; + Ok(()) + } + } + /// Initializes the context for encryption. /// /// Normally this is called once to set all of the cipher, key, and IV. However, this process can be split up @@ -509,6 +528,17 @@ impl CipherCtxRef { Ok(()) } + /// Set ctx flags. + /// + /// This function is currently used to enable AES key wrap feature supported by OpenSSL 1.0.2 or newer. + #[corresponds(EVP_CIPHER_CTX_set_flags)] + #[cfg(ossl102)] + pub fn set_flags(&mut self, flags: CipherCtxFlags) { + unsafe { + ffi::EVP_CIPHER_CTX_set_flags(self.as_ptr(), flags.bits()); + } + } + /// Writes data into the context. /// /// Providing no output buffer will cause the input to be considered additional authenticated data (AAD). @@ -915,4 +945,162 @@ mod test { ctx.cipher_update(&vec![0; block_size + 1], Some(&mut vec![0; block_size - 1])) .unwrap(); } + + #[cfg(ossl102)] + fn cipher_wrap_test(cipher: &CipherRef, pt: &str, ct: &str, key: &str, iv: Option<&str>) { + let pt = hex::decode(pt).unwrap(); + let key = hex::decode(key).unwrap(); + let expected = hex::decode(ct).unwrap(); + let iv = iv.map(|v| hex::decode(v).unwrap()); + let padding = 8 - pt.len() % 8; + let mut computed = vec![0; pt.len() + padding + cipher.block_size() * 2]; + let mut ctx = CipherCtx::new().unwrap(); + + ctx.set_flags(CipherCtxFlags::FLAG_WRAP_ALLOW); + ctx.encrypt_init(Some(cipher), Some(&key), iv.as_deref()) + .unwrap(); + + let count = ctx.cipher_update(&pt, Some(&mut computed)).unwrap(); + let rest = ctx.cipher_final(&mut computed[count..]).unwrap(); + computed.truncate(count + rest); + + if computed != expected { + println!("Computed: {}", hex::encode(&computed)); + println!("Expected: {}", hex::encode(&expected)); + if computed.len() != expected.len() { + println!( + "Lengths differ: {} in computed vs {} expected", + computed.len(), + expected.len() + ); + } + panic!("test failure"); + } + } + + #[test] + #[cfg(ossl102)] + fn test_aes128_wrap() { + let pt = "00112233445566778899aabbccddeeff"; + let ct = "7940ff694448b5bb5139c959a4896832e55d69aa04daa27e"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes128_wrap_default_iv() { + let pt = "00112233445566778899aabbccddeeff"; + let ct = "38f1215f0212526f8a70b51955b9fbdc9fe3041d9832306e"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + + cipher_wrap_test(Cipher::aes_128_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes128_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "f13998f5ab32ef82a1bdbcbe585e1d837385b529572a1e1b"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes128_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "3a501085fb8cf66f4186b7df851914d471ed823411598add"; + let key = "2b7e151628aed2a6abf7158809cf4f3c"; + + cipher_wrap_test(Cipher::aes_128_wrap_pad(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl102)] + fn test_aes192_wrap() { + let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b"; + let ct = "83b89142dfeeb4871e078bfb81134d33e23fedc19b03a1cf689973d3831b6813"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes192_wrap_default_iv() { + let pt = "9f6dee187d35302116aecbfd059657efd9f7589c4b5e7f5b"; + let ct = "c02c2cf11505d3e4851030d5534cbf5a1d7eca7ba8839adbf239756daf1b43e6"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + + cipher_wrap_test(Cipher::aes_192_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes192_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "b4f6bb167ef7caf061a74da82b36ad038ca057ab51e98d3a"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes192_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "b2c37a28cc602753a7c944a4c2555a2df9c98b2eded5312e"; + let key = "8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"; + + cipher_wrap_test(Cipher::aes_192_wrap_pad(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl102)] + fn test_aes256_wrap() { + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"; + let ct = "cc05da2a7f56f7dd0c144231f90bce58648fa20a8278f5a6b7d13bba6aa57a33229d4333866b7fd6"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "0001020304050607"; + + cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl102)] + fn test_aes256_wrap_default_iv() { + let pt = "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"; + let ct = "0b24f068b50e52bc6987868411c36e1b03900866ed12af81eb87cef70a8d1911731c1d7abf789d88"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + + cipher_wrap_test(Cipher::aes_256_wrap(), pt, ct, key, None); + } + + #[test] + #[cfg(ossl110)] + fn test_aes256_wrap_pad() { + let pt = "00112233445566778899aabbccddee"; + let ct = "91594e044ccc06130d60e6c84a996aa4f96a9faff8c5f6e7"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + let iv = "00010203"; + + cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, Some(iv)); + } + + #[test] + #[cfg(ossl110)] + fn test_aes256_wrap_pad_default_iv() { + let pt = "00112233445566778899aabbccddee"; + let ct = "dc3c166a854afd68aea624a4272693554bf2e4fcbae602cd"; + let key = "603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"; + + cipher_wrap_test(Cipher::aes_256_wrap_pad(), pt, ct, key, None); + } } |