Merge pull request #1270 from hargoniX/master
Add support for AES-OCB mode
This commit is contained in:
commit
41ab7f37a5
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()) }
|
||||
}
|
||||
|
|
@ -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()) }
|
||||
}
|
||||
|
|
@ -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()) }
|
||||
}
|
||||
|
|
@ -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 {}
|
||||
|
|
@ -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)?;
|
||||
|
|
@ -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)?;
|
||||
|
|
@ -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…
Reference in New Issue