diff options
author | Igor Matuszewski <igor@sequoia-pgp.org> | 2020-04-10 02:09:38 +0200 |
---|---|---|
committer | Igor Matuszewski <igor@sequoia-pgp.org> | 2020-06-22 11:57:07 +0200 |
commit | c4fbdfea80d12177ed2008f60ee07b453098c090 (patch) | |
tree | 7ceb88f2138a191d8d0d5cd4be693283417091cf /openpgp | |
parent | 61c66c3df5b12f79102eccddf479f58c1a3bdd63 (diff) |
openpgp: Move Nettle symmetric impls to the backend module
Diffstat (limited to 'openpgp')
-rw-r--r-- | openpgp/src/crypto/backend/nettle.rs | 1 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/nettle/symmetric.rs | 146 | ||||
-rw-r--r-- | openpgp/src/crypto/symmetric.rs | 143 |
3 files changed, 175 insertions, 115 deletions
diff --git a/openpgp/src/crypto/backend/nettle.rs b/openpgp/src/crypto/backend/nettle.rs index 25fc64eb..8f9fdeb1 100644 --- a/openpgp/src/crypto/backend/nettle.rs +++ b/openpgp/src/crypto/backend/nettle.rs @@ -6,6 +6,7 @@ pub mod aead; pub mod asymmetric; pub mod ecdh; pub mod hash; +pub mod symmetric; /// Fills the given buffer with random data. pub fn random<B: AsMut<[u8]>>(mut buf: B) { diff --git a/openpgp/src/crypto/backend/nettle/symmetric.rs b/openpgp/src/crypto/backend/nettle/symmetric.rs new file mode 100644 index 00000000..2faaaa03 --- /dev/null +++ b/openpgp/src/crypto/backend/nettle/symmetric.rs @@ -0,0 +1,146 @@ +use nettle::cipher::{self, Cipher}; +use nettle::mode::{self}; + +use crate::crypto::symmetric::Mode; + +use crate::{Error, Result}; +use crate::types::SymmetricAlgorithm; + +impl<T: nettle::mode::Mode> Mode for T { + fn block_size(&self) -> usize { + self.block_size() + } + + fn encrypt( + &mut self, + iv: &mut [u8], + dst: &mut [u8], + src: &[u8], + ) -> Result<()> { + self.encrypt(iv, dst, src) + .map_err(Into::into) + } + + fn decrypt( + &mut self, + iv: &mut [u8], + dst: &mut [u8], + src: &[u8], + ) -> Result<()> { + self.decrypt(iv, dst, src) + .map_err(Into::into) + } +} + +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]) -> Result<Box<dyn Mode>> { + match self { + SymmetricAlgorithm::TripleDES => + Ok(Box::new( + mode::Cfb::<cipher::Des3>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::CAST5 => + Ok(Box::new( + mode::Cfb::<cipher::Cast128>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Blowfish => + Ok(Box::new( + mode::Cfb::<cipher::Blowfish>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::AES128 => + Ok(Box::new( + mode::Cfb::<cipher::Aes128>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::AES192 => + Ok(Box::new( + mode::Cfb::<cipher::Aes192>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::AES256 => + Ok(Box::new( + mode::Cfb::<cipher::Aes256>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Twofish => + Ok(Box::new( + mode::Cfb::<cipher::Twofish>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia128 => + Ok(Box::new( + mode::Cfb::<cipher::Camellia128>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia192 => + Ok(Box::new( + mode::Cfb::<cipher::Camellia192>::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia256 => + Ok(Box::new( + mode::Cfb::<cipher::Camellia256>::with_encrypt_key(&key[..])?)), + _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()), + } + } + + /// Creates a Nettle context for decrypting in CFB mode. + pub(crate) fn make_decrypt_cfb(self, key: &[u8]) -> Result<Box<dyn Mode>> { + match self { + SymmetricAlgorithm::TripleDES => + Ok(Box::new( + mode::Cfb::<cipher::Des3>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::CAST5 => + Ok(Box::new( + mode::Cfb::<cipher::Cast128>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Blowfish => + Ok(Box::new( + mode::Cfb::<cipher::Blowfish>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::AES128 => + Ok(Box::new( + mode::Cfb::<cipher::Aes128>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::AES192 => + Ok(Box::new( + mode::Cfb::<cipher::Aes192>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::AES256 => + Ok(Box::new( + mode::Cfb::<cipher::Aes256>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Twofish => + Ok(Box::new( + mode::Cfb::<cipher::Twofish>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia128 => + Ok(Box::new( + mode::Cfb::<cipher::Camellia128>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia192 => + Ok(Box::new( + mode::Cfb::<cipher::Camellia192>::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia256 => + Ok(Box::new( + mode::Cfb::<cipher::Camellia256>::with_decrypt_key(&key[..])?)), + _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()) + } + } +}
\ No newline at end of file diff --git a/openpgp/src/crypto/symmetric.rs b/openpgp/src/crypto/symmetric.rs index 771a9e41..27738993 100644 --- a/openpgp/src/crypto/symmetric.rs +++ b/openpgp/src/crypto/symmetric.rs @@ -5,126 +5,39 @@ use std::cmp; use std::fmt; use crate::Result; -use crate::Error; use crate::SymmetricAlgorithm; use crate::vec_truncate; use buffered_reader::BufferedReader; -use nettle::cipher::{self, Cipher}; -use nettle::mode::{self, Mode}; - -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]) -> Result<Box<dyn Mode>> { - match self { - SymmetricAlgorithm::TripleDES => - Ok(Box::new( - mode::Cfb::<cipher::Des3>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::CAST5 => - Ok(Box::new( - mode::Cfb::<cipher::Cast128>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Blowfish => - Ok(Box::new( - mode::Cfb::<cipher::Blowfish>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::AES128 => - Ok(Box::new( - mode::Cfb::<cipher::Aes128>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::AES192 => - Ok(Box::new( - mode::Cfb::<cipher::Aes192>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::AES256 => - Ok(Box::new( - mode::Cfb::<cipher::Aes256>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Twofish => - Ok(Box::new( - mode::Cfb::<cipher::Twofish>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia128 => - Ok(Box::new( - mode::Cfb::<cipher::Camellia128>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia192 => - Ok(Box::new( - mode::Cfb::<cipher::Camellia192>::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia256 => - Ok(Box::new( - mode::Cfb::<cipher::Camellia256>::with_encrypt_key(&key[..])?)), - _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()), - } - } - - /// Creates a Nettle context for decrypting in CFB mode. - pub(crate) fn make_decrypt_cfb(self, key: &[u8]) -> Result<Box<dyn Mode>> { - match self { - SymmetricAlgorithm::TripleDES => - Ok(Box::new( - mode::Cfb::<cipher::Des3>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::CAST5 => - Ok(Box::new( - mode::Cfb::<cipher::Cast128>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Blowfish => - Ok(Box::new( - mode::Cfb::<cipher::Blowfish>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::AES128 => - Ok(Box::new( - mode::Cfb::<cipher::Aes128>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::AES192 => - Ok(Box::new( - mode::Cfb::<cipher::Aes192>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::AES256 => - Ok(Box::new( - mode::Cfb::<cipher::Aes256>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Twofish => - Ok(Box::new( - mode::Cfb::<cipher::Twofish>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia128 => - Ok(Box::new( - mode::Cfb::<cipher::Camellia128>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia192 => - Ok(Box::new( - mode::Cfb::<cipher::Camellia192>::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia256 => - Ok(Box::new( - mode::Cfb::<cipher::Camellia256>::with_decrypt_key(&key[..])?)), - _ => Err(Error::UnsupportedSymmetricAlgorithm(self).into()) - } - } +/// Block cipher mode of operation. +/// +/// Block modes govern how a block cipher processes data spanning multiple blocks. +pub(crate) trait Mode { + /// Block size of the underlying cipher in bytes. + fn block_size(&self) -> usize; + + /// Encrypt a single block `src` using the initialization vector `iv` to + /// a ciphertext block `dst`. Both `iv` and dst` are updated. + /// The buffer `iv`, `dst` and `src` are expected to be at least as large as + /// the block size of the underlying cipher. + fn encrypt( + &mut self, + iv: &mut [u8], + dst: &mut [u8], + src: &[u8], + ) -> Result<()>; + + /// Decrypt a single ciphertext block `src` using the initialization vector + /// `iv` to a plaintext block `dst`. Both `iv` and dst` are updated. + /// The buffer `iv`, `dst` and `src` are expected to be at least as large as + /// the block size of the underlying cipher. + fn decrypt( + &mut self, + iv: &mut [u8], + dst: &mut [u8], + src: &[u8], + ) -> Result<()>; } /// A `Read`er for decrypting symmetrically encrypted data. |