From c4fbdfea80d12177ed2008f60ee07b453098c090 Mon Sep 17 00:00:00 2001 From: Igor Matuszewski Date: Fri, 10 Apr 2020 02:09:38 +0200 Subject: openpgp: Move Nettle symmetric impls to the backend module --- openpgp/src/crypto/backend/nettle.rs | 1 + openpgp/src/crypto/backend/nettle/symmetric.rs | 146 +++++++++++++++++++++++++ openpgp/src/crypto/symmetric.rs | 143 +++++------------------- 3 files changed, 175 insertions(+), 115 deletions(-) create mode 100644 openpgp/src/crypto/backend/nettle/symmetric.rs (limited to 'openpgp') 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>(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 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 { + 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 { + 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> { + match self { + SymmetricAlgorithm::TripleDES => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::CAST5 => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Blowfish => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::AES128 => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::AES192 => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::AES256 => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Twofish => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia128 => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia192 => + Ok(Box::new( + mode::Cfb::::with_encrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia256 => + Ok(Box::new( + mode::Cfb::::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> { + match self { + SymmetricAlgorithm::TripleDES => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::CAST5 => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Blowfish => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::AES128 => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::AES192 => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::AES256 => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Twofish => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia128 => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia192 => + Ok(Box::new( + mode::Cfb::::with_decrypt_key(&key[..])?)), + SymmetricAlgorithm::Camellia256 => + Ok(Box::new( + mode::Cfb::::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 { - 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 { - 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> { - match self { - SymmetricAlgorithm::TripleDES => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::CAST5 => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Blowfish => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::AES128 => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::AES192 => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::AES256 => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Twofish => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia128 => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia192 => - Ok(Box::new( - mode::Cfb::::with_encrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia256 => - Ok(Box::new( - mode::Cfb::::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> { - match self { - SymmetricAlgorithm::TripleDES => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::CAST5 => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Blowfish => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::AES128 => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::AES192 => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::AES256 => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Twofish => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia128 => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia192 => - Ok(Box::new( - mode::Cfb::::with_decrypt_key(&key[..])?)), - SymmetricAlgorithm::Camellia256 => - Ok(Box::new( - mode::Cfb::::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. -- cgit v1.2.3