Loading openssl-sys/src/evp.rs +6 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,8 @@ extern "C" { pub fn EVP_aes_128_gcm() -> *const EVP_CIPHER; pub fn EVP_aes_128_xts() -> *const EVP_CIPHER; pub fn EVP_aes_128_ofb() -> *const EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_aes_128_ocb() -> *const EVP_CIPHER; pub fn EVP_aes_192_ecb() -> *const EVP_CIPHER; pub fn EVP_aes_192_cbc() -> *const EVP_CIPHER; pub fn EVP_aes_192_cfb1() -> *const EVP_CIPHER; Loading @@ -284,6 +286,8 @@ extern "C" { pub fn EVP_aes_192_ccm() -> *const EVP_CIPHER; pub fn EVP_aes_192_gcm() -> *const EVP_CIPHER; pub fn EVP_aes_192_ofb() -> *const EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_aes_192_ocb() -> *const EVP_CIPHER; pub fn EVP_aes_256_ecb() -> *const EVP_CIPHER; pub fn EVP_aes_256_cbc() -> *const EVP_CIPHER; pub fn EVP_aes_256_cfb1() -> *const EVP_CIPHER; Loading @@ -295,6 +299,8 @@ extern "C" { pub fn EVP_aes_256_xts() -> *const EVP_CIPHER; pub fn EVP_aes_256_ofb() -> *const EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_aes_256_ocb() -> *const EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_chacha20() -> *const ::EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_chacha20_poly1305() -> *const ::EVP_CIPHER; Loading openssl/src/symm.rs +97 −4 Original line number Diff line number Diff line Loading @@ -130,6 +130,12 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_128_ofb()) } } /// Requires OpenSSL 1.1.0 or newer. #[cfg(ossl110)] pub fn aes_128_ocb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_128_ocb()) } } pub fn aes_192_ecb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_192_ecb()) } } Loading Loading @@ -166,6 +172,12 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_192_ofb()) } } /// Requires OpenSSL 1.1.0 or newer. #[cfg(ossl110)] pub fn aes_192_ocb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_192_ocb()) } } pub fn aes_256_ecb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_256_ecb()) } } Loading Loading @@ -206,6 +218,12 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_256_ofb()) } } /// Requires OpenSSL 1.1.0 or newer. #[cfg(ossl110)] pub fn aes_256_ocb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_256_ocb()) } } pub fn bf_cbc() -> Cipher { unsafe { Cipher(ffi::EVP_bf_cbc()) } } Loading Loading @@ -298,6 +316,19 @@ impl Cipher { // NOTE: OpenSSL returns pointers to static structs, which makes this work as expected *self == Cipher::aes_128_ccm() || *self == Cipher::aes_256_ccm() } /// Determines whether the cipher is using OCB mode #[cfg(ossl110)] fn is_ocb(&self) -> bool { *self == Cipher::aes_128_ocb() || *self == Cipher::aes_192_ocb() || *self == Cipher::aes_256_ocb() } #[cfg(not(ossl110))] const fn is_ocb(&self) -> bool { false } } unsafe impl Sync for Cipher {} Loading Loading @@ -736,10 +767,13 @@ pub fn encrypt_aead( let mut c = Crypter::new(t, Mode::Encrypt, key, iv)?; let mut out = vec![0; data.len() + t.block_size()]; if t.is_ccm() { let is_ccm = t.is_ccm(); if is_ccm || t.is_ocb() { c.set_tag_len(tag.len())?; if is_ccm { c.set_data_len(data.len())?; } } c.aad_update(aad)?; let count = c.update(data, &mut out)?; Loading @@ -764,10 +798,13 @@ pub fn decrypt_aead( let mut c = Crypter::new(t, Mode::Decrypt, key, iv)?; let mut out = vec![0; data.len() + t.block_size()]; if t.is_ccm() { let is_ccm = t.is_ccm(); if is_ccm || t.is_ocb() { c.set_tag(tag)?; if is_ccm { c.set_data_len(data.len())?; } } c.aad_update(aad)?; let count = c.update(data, &mut out)?; Loading Loading @@ -1387,6 +1424,62 @@ mod tests { assert!(out.is_err()); } #[test] #[cfg(ossl110)] fn test_aes_128_ocb() { let key = "000102030405060708090a0b0c0d0e0f"; let aad = "0001020304050607"; let tag = "16dc76a46d47e1ead537209e8a96d14e"; let iv = "000102030405060708090a0b"; let pt = "0001020304050607"; let ct = "92b657130a74b85a"; let mut actual_tag = [0; 16]; let out = encrypt_aead( Cipher::aes_128_ocb(), &Vec::from_hex(key).unwrap(), Some(&Vec::from_hex(iv).unwrap()), &Vec::from_hex(aad).unwrap(), &Vec::from_hex(pt).unwrap(), &mut actual_tag, ) .unwrap(); assert_eq!(ct, hex::encode(out)); assert_eq!(tag, hex::encode(actual_tag)); let out = decrypt_aead( Cipher::aes_128_ocb(), &Vec::from_hex(key).unwrap(), Some(&Vec::from_hex(iv).unwrap()), &Vec::from_hex(aad).unwrap(), &Vec::from_hex(ct).unwrap(), &Vec::from_hex(tag).unwrap(), ) .unwrap(); assert_eq!(pt, hex::encode(out)); } #[test] #[cfg(ossl110)] fn test_aes_128_ocb_fail() { let key = "000102030405060708090a0b0c0d0e0f"; let aad = "0001020304050607"; let tag = "16dc76a46d47e1ead537209e8a96d14e"; let iv = "000000000405060708090a0b"; let ct = "92b657130a74b85a"; let out = decrypt_aead( Cipher::aes_128_ocb(), &Vec::from_hex(key).unwrap(), Some(&Vec::from_hex(iv).unwrap()), &Vec::from_hex(aad).unwrap(), &Vec::from_hex(ct).unwrap(), &Vec::from_hex(tag).unwrap(), ); assert!(out.is_err()); } #[test] #[cfg(any(ossl110))] fn test_chacha20() { Loading Loading
openssl-sys/src/evp.rs +6 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,8 @@ extern "C" { pub fn EVP_aes_128_gcm() -> *const EVP_CIPHER; pub fn EVP_aes_128_xts() -> *const EVP_CIPHER; pub fn EVP_aes_128_ofb() -> *const EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_aes_128_ocb() -> *const EVP_CIPHER; pub fn EVP_aes_192_ecb() -> *const EVP_CIPHER; pub fn EVP_aes_192_cbc() -> *const EVP_CIPHER; pub fn EVP_aes_192_cfb1() -> *const EVP_CIPHER; Loading @@ -284,6 +286,8 @@ extern "C" { pub fn EVP_aes_192_ccm() -> *const EVP_CIPHER; pub fn EVP_aes_192_gcm() -> *const EVP_CIPHER; pub fn EVP_aes_192_ofb() -> *const EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_aes_192_ocb() -> *const EVP_CIPHER; pub fn EVP_aes_256_ecb() -> *const EVP_CIPHER; pub fn EVP_aes_256_cbc() -> *const EVP_CIPHER; pub fn EVP_aes_256_cfb1() -> *const EVP_CIPHER; Loading @@ -295,6 +299,8 @@ extern "C" { pub fn EVP_aes_256_xts() -> *const EVP_CIPHER; pub fn EVP_aes_256_ofb() -> *const EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_aes_256_ocb() -> *const EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_chacha20() -> *const ::EVP_CIPHER; #[cfg(ossl110)] pub fn EVP_chacha20_poly1305() -> *const ::EVP_CIPHER; Loading
openssl/src/symm.rs +97 −4 Original line number Diff line number Diff line Loading @@ -130,6 +130,12 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_128_ofb()) } } /// Requires OpenSSL 1.1.0 or newer. #[cfg(ossl110)] pub fn aes_128_ocb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_128_ocb()) } } pub fn aes_192_ecb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_192_ecb()) } } Loading Loading @@ -166,6 +172,12 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_192_ofb()) } } /// Requires OpenSSL 1.1.0 or newer. #[cfg(ossl110)] pub fn aes_192_ocb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_192_ocb()) } } pub fn aes_256_ecb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_256_ecb()) } } Loading Loading @@ -206,6 +218,12 @@ impl Cipher { unsafe { Cipher(ffi::EVP_aes_256_ofb()) } } /// Requires OpenSSL 1.1.0 or newer. #[cfg(ossl110)] pub fn aes_256_ocb() -> Cipher { unsafe { Cipher(ffi::EVP_aes_256_ocb()) } } pub fn bf_cbc() -> Cipher { unsafe { Cipher(ffi::EVP_bf_cbc()) } } Loading Loading @@ -298,6 +316,19 @@ impl Cipher { // NOTE: OpenSSL returns pointers to static structs, which makes this work as expected *self == Cipher::aes_128_ccm() || *self == Cipher::aes_256_ccm() } /// Determines whether the cipher is using OCB mode #[cfg(ossl110)] fn is_ocb(&self) -> bool { *self == Cipher::aes_128_ocb() || *self == Cipher::aes_192_ocb() || *self == Cipher::aes_256_ocb() } #[cfg(not(ossl110))] const fn is_ocb(&self) -> bool { false } } unsafe impl Sync for Cipher {} Loading Loading @@ -736,10 +767,13 @@ pub fn encrypt_aead( let mut c = Crypter::new(t, Mode::Encrypt, key, iv)?; let mut out = vec![0; data.len() + t.block_size()]; if t.is_ccm() { let is_ccm = t.is_ccm(); if is_ccm || t.is_ocb() { c.set_tag_len(tag.len())?; if is_ccm { c.set_data_len(data.len())?; } } c.aad_update(aad)?; let count = c.update(data, &mut out)?; Loading @@ -764,10 +798,13 @@ pub fn decrypt_aead( let mut c = Crypter::new(t, Mode::Decrypt, key, iv)?; let mut out = vec![0; data.len() + t.block_size()]; if t.is_ccm() { let is_ccm = t.is_ccm(); if is_ccm || t.is_ocb() { c.set_tag(tag)?; if is_ccm { c.set_data_len(data.len())?; } } c.aad_update(aad)?; let count = c.update(data, &mut out)?; Loading Loading @@ -1387,6 +1424,62 @@ mod tests { assert!(out.is_err()); } #[test] #[cfg(ossl110)] fn test_aes_128_ocb() { let key = "000102030405060708090a0b0c0d0e0f"; let aad = "0001020304050607"; let tag = "16dc76a46d47e1ead537209e8a96d14e"; let iv = "000102030405060708090a0b"; let pt = "0001020304050607"; let ct = "92b657130a74b85a"; let mut actual_tag = [0; 16]; let out = encrypt_aead( Cipher::aes_128_ocb(), &Vec::from_hex(key).unwrap(), Some(&Vec::from_hex(iv).unwrap()), &Vec::from_hex(aad).unwrap(), &Vec::from_hex(pt).unwrap(), &mut actual_tag, ) .unwrap(); assert_eq!(ct, hex::encode(out)); assert_eq!(tag, hex::encode(actual_tag)); let out = decrypt_aead( Cipher::aes_128_ocb(), &Vec::from_hex(key).unwrap(), Some(&Vec::from_hex(iv).unwrap()), &Vec::from_hex(aad).unwrap(), &Vec::from_hex(ct).unwrap(), &Vec::from_hex(tag).unwrap(), ) .unwrap(); assert_eq!(pt, hex::encode(out)); } #[test] #[cfg(ossl110)] fn test_aes_128_ocb_fail() { let key = "000102030405060708090a0b0c0d0e0f"; let aad = "0001020304050607"; let tag = "16dc76a46d47e1ead537209e8a96d14e"; let iv = "000000000405060708090a0b"; let ct = "92b657130a74b85a"; let out = decrypt_aead( Cipher::aes_128_ocb(), &Vec::from_hex(key).unwrap(), Some(&Vec::from_hex(iv).unwrap()), &Vec::from_hex(aad).unwrap(), &Vec::from_hex(ct).unwrap(), &Vec::from_hex(tag).unwrap(), ); assert!(out.is_err()); } #[test] #[cfg(any(ossl110))] fn test_chacha20() { Loading