summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-03-23 17:37:08 +0100
committerJustus Winter <justus@sequoia-pgp.org>2023-03-24 10:08:31 +0100
commit301ad2858cf43b06f398214d87c8b5bf24dffa79 (patch)
treebc13d6713451b82ed046a818be0990e6bc021ca7
parent6f801ea5e5b884711945d49bc8e6589e150983d2 (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.rs41
-rw-r--r--openpgp/src/crypto/backend/cng/symmetric.rs26
-rw-r--r--openpgp/src/crypto/backend/nettle/symmetric.rs98
-rw-r--r--openpgp/src/crypto/backend/openssl/symmetric.rs43
-rw-r--r--openpgp/src/crypto/backend/rust/symmetric.rs89
-rw-r--r--openpgp/src/types/mod.rs41
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].