summaryrefslogtreecommitdiffstats
path: root/openpgp/src/crypto/backend/nettle/symmetric.rs
diff options
context:
space:
mode:
Diffstat (limited to 'openpgp/src/crypto/backend/nettle/symmetric.rs')
-rw-r--r--openpgp/src/crypto/backend/nettle/symmetric.rs146
1 files changed, 146 insertions, 0 deletions
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