diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2023-03-23 17:37:08 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2023-03-24 10:08:31 +0100 |
commit | 301ad2858cf43b06f398214d87c8b5bf24dffa79 (patch) | |
tree | bc13d6713451b82ed046a818be0990e6bc021ca7 | |
parent | 6f801ea5e5b884711945d49bc8e6589e150983d2 (diff) |
openpgp: Hardcode symmetric algorithm key and block sizes.
- Previously, every crypto backend had to implement these methods.
Instead, implement them just once and hard code the lengths.
Anchor them using the values from the crypto backends, if
available.
- Fixes #966.
-rw-r--r-- | openpgp/src/crypto/backend/botan/symmetric.rs | 41 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/cng/symmetric.rs | 26 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/nettle/symmetric.rs | 98 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/openssl/symmetric.rs | 43 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/rust/symmetric.rs | 89 | ||||
-rw-r--r-- | openpgp/src/types/mod.rs | 41 |
6 files changed, 180 insertions, 158 deletions
diff --git a/openpgp/src/crypto/backend/botan/symmetric.rs b/openpgp/src/crypto/backend/botan/symmetric.rs index 4b5afd74..759d3f4f 100644 --- a/openpgp/src/crypto/backend/botan/symmetric.rs +++ b/openpgp/src/crypto/backend/botan/symmetric.rs @@ -77,47 +77,6 @@ impl SymmetricAlgorithm { } } - /// Length of a key for this algorithm in bytes. - /// - /// Fails if Sequoia does not support this algorithm. - pub fn key_size(self) -> Result<usize> { - match self { - SymmetricAlgorithm::IDEA => Ok(16), - SymmetricAlgorithm::TripleDES => Ok(24), - SymmetricAlgorithm::CAST5 => Ok(16), - // RFC4880, Section 9.2: Blowfish (128 bit key, 16 rounds) - SymmetricAlgorithm::Blowfish => Ok(16), - SymmetricAlgorithm::AES128 => Ok(16), - SymmetricAlgorithm::AES192 => Ok(24), - SymmetricAlgorithm::AES256 => Ok(32), - SymmetricAlgorithm::Twofish => Ok(32), - SymmetricAlgorithm::Camellia128 => Ok(16), - SymmetricAlgorithm::Camellia192 => Ok(24), - SymmetricAlgorithm::Camellia256 => Ok(32), - _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - - /// Length of a block for this algorithm in bytes. - /// - /// Fails if Sequoia does not support this algorithm. - pub fn block_size(self) -> Result<usize> { - match self { - SymmetricAlgorithm::IDEA => Ok(8), - SymmetricAlgorithm::TripleDES => Ok(8), - SymmetricAlgorithm::CAST5 => Ok(8), - SymmetricAlgorithm::Blowfish => Ok(8), - SymmetricAlgorithm::AES128 => Ok(16), - SymmetricAlgorithm::AES192 => Ok(16), - SymmetricAlgorithm::AES256 => Ok(16), - SymmetricAlgorithm::Twofish => Ok(16), - SymmetricAlgorithm::Camellia128 => Ok(16), - SymmetricAlgorithm::Camellia192 => Ok(16), - SymmetricAlgorithm::Camellia256 => Ok(16), - _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - /// Returns the name of the algorithm for use with Botan's /// constructor. pub(crate) fn botan_name(self) -> Result<&'static str> { diff --git a/openpgp/src/crypto/backend/cng/symmetric.rs b/openpgp/src/crypto/backend/cng/symmetric.rs index 27ee095f..481a5404 100644 --- a/openpgp/src/crypto/backend/cng/symmetric.rs +++ b/openpgp/src/crypto/backend/cng/symmetric.rs @@ -134,32 +134,6 @@ impl SymmetricAlgorithm { } } - /// Length of a key for this algorithm in bytes. - /// - /// Fails if the crypto backend does not support this algorithm. - pub fn key_size(self) -> Result<usize> { - Ok(match self { - SymmetricAlgorithm::TripleDES => 24, - SymmetricAlgorithm::AES128 => 16, - SymmetricAlgorithm::AES192 => 24, - SymmetricAlgorithm::AES256 => 32, - _ => Err(UnsupportedAlgorithm(self))?, - }) - } - - /// Length of a block for this algorithm in bytes. - /// - /// Fails if the crypto backend does not support this algorithm. - pub fn block_size(self) -> Result<usize> { - Ok(match self { - SymmetricAlgorithm::TripleDES => 8, - SymmetricAlgorithm::AES128 => 16, - SymmetricAlgorithm::AES192 => 16, - SymmetricAlgorithm::AES256 => 16, - _ => Err(UnsupportedAlgorithm(self))?, - }) - } - /// Creates a symmetric cipher context for encrypting in CFB mode. pub(crate) fn make_encrypt_cfb(self, key: &[u8], iv: Vec<u8>) -> Result<Box<dyn Mode>> { let (algo, _) = TryFrom::try_from(self)?; diff --git a/openpgp/src/crypto/backend/nettle/symmetric.rs b/openpgp/src/crypto/backend/nettle/symmetric.rs index b9dd2703..2b3c9f1b 100644 --- a/openpgp/src/crypto/backend/nettle/symmetric.rs +++ b/openpgp/src/crypto/backend/nettle/symmetric.rs @@ -109,45 +109,6 @@ impl SymmetricAlgorithm { } } - /// Length of a key for this algorithm in bytes. - /// - /// Fails if Sequoia does not support this algorithm. - pub fn key_size(self) -> Result<usize> { - match self { - SymmetricAlgorithm::TripleDES => Ok(cipher::Des3::KEY_SIZE), - SymmetricAlgorithm::CAST5 => Ok(cipher::Cast128::KEY_SIZE), - // RFC4880, Section 9.2: Blowfish (128 bit key, 16 rounds) - SymmetricAlgorithm::Blowfish => Ok(16), - SymmetricAlgorithm::AES128 => Ok(cipher::Aes128::KEY_SIZE), - SymmetricAlgorithm::AES192 => Ok(cipher::Aes192::KEY_SIZE), - SymmetricAlgorithm::AES256 => Ok(cipher::Aes256::KEY_SIZE), - SymmetricAlgorithm::Twofish => Ok(cipher::Twofish::KEY_SIZE), - SymmetricAlgorithm::Camellia128 => Ok(cipher::Camellia128::KEY_SIZE), - SymmetricAlgorithm::Camellia192 => Ok(cipher::Camellia192::KEY_SIZE), - SymmetricAlgorithm::Camellia256 => Ok(cipher::Camellia256::KEY_SIZE), - _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - - /// Length of a block for this algorithm in bytes. - /// - /// Fails if Sequoia does not support this algorithm. - pub fn block_size(self) -> Result<usize> { - match self { - SymmetricAlgorithm::TripleDES => Ok(cipher::Des3::BLOCK_SIZE), - SymmetricAlgorithm::CAST5 => Ok(cipher::Cast128::BLOCK_SIZE), - SymmetricAlgorithm::Blowfish => Ok(cipher::Blowfish::BLOCK_SIZE), - SymmetricAlgorithm::AES128 => Ok(cipher::Aes128::BLOCK_SIZE), - SymmetricAlgorithm::AES192 => Ok(cipher::Aes192::BLOCK_SIZE), - SymmetricAlgorithm::AES256 => Ok(cipher::Aes256::BLOCK_SIZE), - SymmetricAlgorithm::Twofish => Ok(cipher::Twofish::BLOCK_SIZE), - SymmetricAlgorithm::Camellia128 => Ok(cipher::Camellia128::BLOCK_SIZE), - SymmetricAlgorithm::Camellia192 => Ok(cipher::Camellia192::BLOCK_SIZE), - SymmetricAlgorithm::Camellia256 => Ok(cipher::Camellia256::BLOCK_SIZE), - _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - /// Creates a Nettle context for encrypting in CFB mode. pub(crate) fn make_encrypt_cfb(self, key: &[u8], iv: Vec<u8>) -> Result<Box<dyn Mode>> { match self { @@ -256,3 +217,62 @@ impl SymmetricAlgorithm { } } } + +#[cfg(test)] +mod tests { + use super::*; + + /// Anchors the constants used in Sequoia with the ones from + /// Nettle. + #[test] + fn key_size() -> Result<()> { + assert_eq!(SymmetricAlgorithm::TripleDES.key_size()?, + cipher::Des3::KEY_SIZE); + assert_eq!(SymmetricAlgorithm::CAST5.key_size()?, + cipher::Cast128::KEY_SIZE); + // RFC4880, Section 9.2: Blowfish (128 bit key, 16 rounds) + assert_eq!(SymmetricAlgorithm::Blowfish.key_size()?, 16); + assert_eq!(SymmetricAlgorithm::AES128.key_size()?, + cipher::Aes128::KEY_SIZE); + assert_eq!(SymmetricAlgorithm::AES192.key_size()?, + cipher::Aes192::KEY_SIZE); + assert_eq!(SymmetricAlgorithm::AES256.key_size()?, + cipher::Aes256::KEY_SIZE); + assert_eq!(SymmetricAlgorithm::Twofish.key_size()?, + cipher::Twofish::KEY_SIZE); + assert_eq!(SymmetricAlgorithm::Camellia128.key_size()?, + cipher::Camellia128::KEY_SIZE); + assert_eq!(SymmetricAlgorithm::Camellia192.key_size()?, + cipher::Camellia192::KEY_SIZE); + assert_eq!(SymmetricAlgorithm::Camellia256.key_size()?, + cipher::Camellia256::KEY_SIZE); + Ok(()) + } + + /// Anchors the constants used in Sequoia with the ones from + /// Nettle. + #[test] + fn block_size() -> Result<()> { + assert_eq!(SymmetricAlgorithm::TripleDES.block_size()?, + cipher::Des3::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::CAST5.block_size()?, + cipher::Cast128::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::Blowfish.block_size()?, + cipher::Blowfish::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::AES128.block_size()?, + cipher::Aes128::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::AES192.block_size()?, + cipher::Aes192::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::AES256.block_size()?, + cipher::Aes256::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::Twofish.block_size()?, + cipher::Twofish::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::Camellia128.block_size()?, + cipher::Camellia128::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::Camellia192.block_size()?, + cipher::Camellia192::BLOCK_SIZE); + assert_eq!(SymmetricAlgorithm::Camellia256.block_size()?, + cipher::Camellia256::BLOCK_SIZE); + Ok(()) + } +} diff --git a/openpgp/src/crypto/backend/openssl/symmetric.rs b/openpgp/src/crypto/backend/openssl/symmetric.rs index 605d7533..aa2cff01 100644 --- a/openpgp/src/crypto/backend/openssl/symmetric.rs +++ b/openpgp/src/crypto/backend/openssl/symmetric.rs @@ -91,20 +91,6 @@ impl SymmetricAlgorithm { ctx.encrypt_init(Some(cipher), None, None).is_ok() } - /// Length of a key for this algorithm in bytes. - /// - /// Fails if Sequoia does not support this algorithm. - pub fn key_size(self) -> Result<usize> { - Ok(self.make_cfb_cipher()?.key_length()) - } - - /// Length of a block for this algorithm in bytes. - /// - /// Fails if Sequoia does not support this algorithm. - pub fn block_size(self) -> Result<usize> { - Ok(self.make_ecb_cipher()?.block_size()) - } - /// Creates a OpenSSL context for encrypting in CFB mode. pub(crate) fn make_encrypt_cfb(self, key: &[u8], iv: Vec<u8>) -> Result<Box<dyn Mode>> { let cipher = self.make_cfb_cipher()?; @@ -193,3 +179,32 @@ impl SymmetricAlgorithm { }) } } + +#[cfg(test)] +mod tests { + use super::*; + + /// Anchors the constants used in Sequoia with the ones from + /// OpenSSL. + #[test] + fn key_size() -> Result<()> { + for a in SymmetricAlgorithm::variants() { + if let Ok(cipher) = a.make_cfb_cipher() { + assert_eq!(a.key_size()?, cipher.key_length()); + } + } + Ok(()) + } + + /// Anchors the constants used in Sequoia with the ones from + /// OpenSSL. + #[test] + fn block_size() -> Result<()> { + for a in SymmetricAlgorithm::variants() { + if let Ok(cipher) = a.make_ecb_cipher() { + assert_eq!(a.block_size()?, cipher.block_size()); + } + } + Ok(()) + } +} diff --git a/openpgp/src/crypto/backend/rust/symmetric.rs b/openpgp/src/crypto/backend/rust/symmetric.rs index 73089e72..c419dbc3 100644 --- a/openpgp/src/crypto/backend/rust/symmetric.rs +++ b/openpgp/src/crypto/backend/rust/symmetric.rs @@ -115,44 +115,6 @@ impl SymmetricAlgorithm { } } - /// Length of a key for this algorithm in bytes. - /// - /// Fails if Sequoia does not support this algorithm. - pub fn key_size(self) -> Result<usize> { - use SymmetricAlgorithm::*; - match self { - IDEA => Ok(<idea::Idea as NewBlockCipher>::KeySize::to_usize()), - TripleDES => Ok(<des::TdesEde3 as NewBlockCipher>::KeySize::to_usize()), - CAST5 => Ok(<cast5::Cast5 as NewBlockCipher>::KeySize::to_usize()), - Blowfish => Ok(<blowfish::Blowfish as NewBlockCipher>::KeySize::to_usize()), - AES128 => Ok(<aes::Aes128 as NewBlockCipher>::KeySize::to_usize()), - AES192 => Ok(<aes::Aes192 as NewBlockCipher>::KeySize::to_usize()), - AES256 => Ok(<aes::Aes256 as NewBlockCipher>::KeySize::to_usize()), - Twofish => Ok(<twofish::Twofish as NewBlockCipher>::KeySize::to_usize()), - Camellia128 | Camellia192 | Camellia256 | Private(_) | Unknown(_) | Unencrypted => - Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - - /// Length of a block for this algorithm in bytes. - /// - /// Fails if Sequoia does not support this algorithm. - pub fn block_size(self) -> Result<usize> { - use SymmetricAlgorithm::*; - match self { - IDEA => Ok(<idea::Idea as BlockCipher>::BlockSize::to_usize()), - TripleDES => Ok(<des::TdesEde3 as BlockCipher>::BlockSize::to_usize()), - CAST5 => Ok(<cast5::Cast5 as BlockCipher>::BlockSize::to_usize()), - Blowfish => Ok(<blowfish::Blowfish as BlockCipher>::BlockSize::to_usize()), - AES128 => Ok(<aes::Aes128 as BlockCipher>::BlockSize::to_usize()), - AES192 => Ok(<aes::Aes192 as BlockCipher>::BlockSize::to_usize()), - AES256 => Ok(<aes::Aes256 as BlockCipher>::BlockSize::to_usize()), - Twofish => Ok(<twofish::Twofish as BlockCipher>::BlockSize::to_usize()), - Camellia128 | Camellia192 | Camellia256 | Private(_) | Unknown(_) | Unencrypted => - Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - /// Creates a context for encrypting in CFB mode. pub(crate) fn make_encrypt_cfb(self, key: &[u8], iv: Vec<u8>) -> Result<Box<dyn Mode>> { use SymmetricAlgorithm::*; @@ -197,3 +159,54 @@ impl SymmetricAlgorithm { self.make_encrypt_ecb(key) } } + +#[cfg(test)] +mod tests { + use super::*; + + /// Anchors the constants used in Sequoia with the ones from + /// RustCrypto. + #[test] + fn key_size() -> Result<()> { + assert_eq!(SymmetricAlgorithm::IDEA.key_size()?, + <idea::Idea as NewBlockCipher>::KeySize::to_usize()); + assert_eq!(SymmetricAlgorithm::TripleDES.key_size()?, + <des::TdesEde3 as NewBlockCipher>::KeySize::to_usize()); + assert_eq!(SymmetricAlgorithm::CAST5.key_size()?, + <cast5::Cast5 as NewBlockCipher>::KeySize::to_usize()); + // RFC4880, Section 9.2: Blowfish (128 bit key, 16 rounds) + assert_eq!(SymmetricAlgorithm::Blowfish.key_size()?, 16); + assert_eq!(SymmetricAlgorithm::AES128.key_size()?, + <aes::Aes128 as NewBlockCipher>::KeySize::to_usize()); + assert_eq!(SymmetricAlgorithm::AES192.key_size()?, + <aes::Aes192 as NewBlockCipher>::KeySize::to_usize()); + assert_eq!(SymmetricAlgorithm::AES256.key_size()?, + <aes::Aes256 as NewBlockCipher>::KeySize::to_usize()); + assert_eq!(SymmetricAlgorithm::Twofish.key_size()?, + <twofish::Twofish as NewBlockCipher>::KeySize::to_usize()); + Ok(()) + } + + /// Anchors the constants used in Sequoia with the ones from + /// RustCrypto. + #[test] + fn block_size() -> Result<()> { + assert_eq!(SymmetricAlgorithm::IDEA.block_size()?, + <idea::Idea as BlockCipher>::BlockSize::to_usize()); + assert_eq!(SymmetricAlgorithm::TripleDES.block_size()?, + <des::TdesEde3 as BlockCipher>::BlockSize::to_usize()); + assert_eq!(SymmetricAlgorithm::CAST5.block_size()?, + <cast5::Cast5 as BlockCipher>::BlockSize::to_usize()); + assert_eq!(SymmetricAlgorithm::Blowfish.block_size()?, + <blowfish::Blowfish as BlockCipher>::BlockSize::to_usize()); + assert_eq!(SymmetricAlgorithm::AES128.block_size()?, + <aes::Aes128 as BlockCipher>::BlockSize::to_usize()); + assert_eq!(SymmetricAlgorithm::AES192.block_size()?, + <aes::Aes192 as BlockCipher>::BlockSize::to_usize()); + assert_eq!(SymmetricAlgorithm::AES256.block_size()?, + <aes::Aes256 as BlockCipher>::BlockSize::to_usize()); + assert_eq!(SymmetricAlgorithm::Twofish.block_size()?, + <twofish::Twofish as BlockCipher>::BlockSize::to_usize()); + Ok(()) + } +} diff --git a/openpgp/src/types/mod.rs b/openpgp/src/types/mod.rs index 698b65d1..eca26d92 100644 --- a/openpgp/src/types/mod.rs +++ b/openpgp/src/types/mod.rs @@ -862,6 +862,47 @@ impl SymmetricAlgorithm { pub fn variants() -> impl Iterator<Item=Self> { SYMMETRIC_ALGORITHM_VARIANTS.iter().cloned() } + + /// Length of a key for this algorithm in bytes. + /// + /// Fails if the algorithm isn't known to Sequoia. + pub fn key_size(self) -> Result<usize> { + match self { + SymmetricAlgorithm::IDEA => Ok(16), + SymmetricAlgorithm::TripleDES => Ok(24), + SymmetricAlgorithm::CAST5 => Ok(16), + // RFC4880, Section 9.2: Blowfish (128 bit key, 16 rounds) + SymmetricAlgorithm::Blowfish => Ok(16), + SymmetricAlgorithm::AES128 => Ok(16), + SymmetricAlgorithm::AES192 => Ok(24), + SymmetricAlgorithm::AES256 => Ok(32), + SymmetricAlgorithm::Twofish => Ok(32), + SymmetricAlgorithm::Camellia128 => Ok(16), + SymmetricAlgorithm::Camellia192 => Ok(24), + SymmetricAlgorithm::Camellia256 => Ok(32), + _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()), + } + } + + /// Length of a block for this algorithm in bytes. + /// + /// Fails if the algorithm isn't known to Sequoia. + pub fn block_size(self) -> Result<usize> { + match self { + SymmetricAlgorithm::IDEA => Ok(8), + SymmetricAlgorithm::TripleDES => Ok(8), + SymmetricAlgorithm::CAST5 => Ok(8), + SymmetricAlgorithm::Blowfish => Ok(8), + SymmetricAlgorithm::AES128 => Ok(16), + SymmetricAlgorithm::AES192 => Ok(16), + SymmetricAlgorithm::AES256 => Ok(16), + SymmetricAlgorithm::Twofish => Ok(16), + SymmetricAlgorithm::Camellia128 => Ok(16), + SymmetricAlgorithm::Camellia192 => Ok(16), + SymmetricAlgorithm::Camellia256 => Ok(16), + _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()), + } + } } /// The AEAD algorithms as defined in [Section 9.6 of RFC 4880bis]. |