summaryrefslogtreecommitdiffstats
path: root/openpgp
diff options
context:
space:
mode:
authorIgor Matuszewski <igor@sequoia-pgp.org>2020-04-10 02:09:38 +0200
committerIgor Matuszewski <igor@sequoia-pgp.org>2020-06-22 11:57:07 +0200
commitc4fbdfea80d12177ed2008f60ee07b453098c090 (patch)
tree7ceb88f2138a191d8d0d5cd4be693283417091cf /openpgp
parent61c66c3df5b12f79102eccddf479f58c1a3bdd63 (diff)
openpgp: Move Nettle symmetric impls to the backend module
Diffstat (limited to 'openpgp')
-rw-r--r--openpgp/src/crypto/backend/nettle.rs1
-rw-r--r--openpgp/src/crypto/backend/nettle/symmetric.rs146
-rw-r--r--openpgp/src/crypto/symmetric.rs143
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.