diff options
author | Igor Matuszewski <igor@sequoia-pgp.org> | 2020-04-10 00:53:35 +0200 |
---|---|---|
committer | Igor Matuszewski <igor@sequoia-pgp.org> | 2020-06-22 11:57:07 +0200 |
commit | c8c207e931f204e5746eaff7dd57382048d26492 (patch) | |
tree | 1482b26870f6f2cd54395255f5443ce1c25dc5a5 /openpgp/src | |
parent | f30cc7f367084fa295bd542cf9eb9a3398657fce (diff) |
openpgp: Move Nettle AEAD implementation to the backend module
Diffstat (limited to 'openpgp/src')
-rw-r--r-- | openpgp/src/crypto/aead.rs | 75 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/nettle.rs | 1 | ||||
-rw-r--r-- | openpgp/src/crypto/backend/nettle/aead.rs | 62 |
3 files changed, 90 insertions, 48 deletions
diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs index 61cfd7f7..5858aacb 100644 --- a/openpgp/src/crypto/aead.rs +++ b/openpgp/src/crypto/aead.rs @@ -3,7 +3,6 @@ use std::convert::TryInto; use std::fmt; use std::io; -use nettle::{aead, cipher}; use buffered_reader::BufferedReader; use crate::types::{ @@ -33,17 +32,32 @@ pub(crate) fn chunk_size_usize(chunk_size: u64) -> Result<usize> { virtual memory: {}", chunk_size)).into()) } +/// An AEAD mode of operation. +pub trait Aead { + /// Adds associated data `ad`. + fn update(&mut self, ad: &[u8]); + + /// Encrypts one block `src` to `dst`. + fn encrypt(&mut self, dst: &mut [u8], src: &[u8]); + /// Decrypts one block `src` to `dst`. + fn decrypt(&mut self, dst: &mut [u8], src: &[u8]); + + /// Produce the digest. + fn digest(&mut self, digest: &mut [u8]); + + /// Length of the digest in bytes. + fn digest_size(&self) -> usize; +} + impl AEADAlgorithm { /// Returns the digest size of the AEAD algorithm. pub fn digest_size(&self) -> Result<usize> { use self::AEADAlgorithm::*; match self { - &EAX => - // Digest size is independent of the cipher. - Ok(aead::Eax::<cipher::Aes128>::DIGEST_SIZE), - &OCB => + // According to RFC4880bis, Section 5.16.1. + EAX => Ok(16), // According to RFC4880bis, Section 5.16.2. - Ok(16), + OCB => Ok(16), _ => Err(Error::UnsupportedAEADAlgorithm(self.clone()).into()), } } @@ -52,50 +66,15 @@ impl AEADAlgorithm { pub fn iv_size(&self) -> Result<usize> { use self::AEADAlgorithm::*; match self { - &EAX => - Ok(16), // According to RFC4880bis, Section 5.16.1. - &OCB => + // According to RFC4880bis, Section 5.16.1. + EAX => Ok(16), // According to RFC4880bis, Section 5.16.2, the IV is "at // least 15 octets long". GnuPG hardcodes 15 in // openpgp_aead_algo_info. - Ok(15), + OCB => Ok(15), _ => Err(Error::UnsupportedAEADAlgorithm(self.clone()).into()), } } - - /// Creates a Nettle context. - pub(crate) fn context(&self, sym_algo: SymmetricAlgorithm, key: &[u8], nonce: &[u8]) - -> Result<Box<dyn aead::Aead>> { - match self { - AEADAlgorithm::EAX => match sym_algo { - SymmetricAlgorithm::AES128 => - Ok(Box::new(aead::Eax::<cipher::Aes128> - ::with_key_and_nonce(key, nonce)?)), - SymmetricAlgorithm::AES192 => - Ok(Box::new(aead::Eax::<cipher::Aes192> - ::with_key_and_nonce(key, nonce)?)), - SymmetricAlgorithm::AES256 => - Ok(Box::new(aead::Eax::<cipher::Aes256> - ::with_key_and_nonce(key, nonce)?)), - SymmetricAlgorithm::Twofish => - Ok(Box::new(aead::Eax::<cipher::Twofish> - ::with_key_and_nonce(key, nonce)?)), - SymmetricAlgorithm::Camellia128 => - Ok(Box::new(aead::Eax::<cipher::Camellia128> - ::with_key_and_nonce(key, nonce)?)), - SymmetricAlgorithm::Camellia192 => - Ok(Box::new(aead::Eax::<cipher::Camellia192> - ::with_key_and_nonce(key, nonce)?)), - SymmetricAlgorithm::Camellia256 => - Ok(Box::new(aead::Eax::<cipher::Camellia256> - ::with_key_and_nonce(key, nonce)?)), - _ => - Err(Error::UnsupportedSymmetricAlgorithm(sym_algo).into()), - }, - _ => - Err(Error::UnsupportedAEADAlgorithm(self.clone()).into()), - } - } } const AD_PREFIX_LEN: usize = 5; @@ -164,7 +143,7 @@ impl<'a> Decryptor<'a> { }) } - fn hash_associated_data(&mut self, aead: &mut Box<dyn aead::Aead>, + fn hash_associated_data(&mut self, aead: &mut Box<dyn Aead>, final_digest: bool) { // Prepare the associated data. write_be_u64(&mut self.ad[AD_PREFIX_LEN..AD_PREFIX_LEN + 8], @@ -179,7 +158,7 @@ impl<'a> Decryptor<'a> { } } - fn make_aead(&mut self) -> Result<Box<dyn aead::Aead>> { + fn make_aead(&mut self) -> Result<Box<dyn Aead>> { // The chunk index is XORed into the IV. let mut chunk_index_be64 = vec![0u8; 8]; write_be_u64(&mut chunk_index_be64, self.chunk_index); @@ -582,7 +561,7 @@ impl<W: io::Write> Encryptor<W> { }) } - fn hash_associated_data(&mut self, aead: &mut Box<dyn aead::Aead>, + fn hash_associated_data(&mut self, aead: &mut Box<dyn Aead>, final_digest: bool) { // Prepare the associated data. write_be_u64(&mut self.ad[AD_PREFIX_LEN..AD_PREFIX_LEN + 8], @@ -597,7 +576,7 @@ impl<W: io::Write> Encryptor<W> { } } - fn make_aead(&mut self) -> Result<Box<dyn aead::Aead>> { + fn make_aead(&mut self) -> Result<Box<dyn Aead>> { // The chunk index is XORed into the IV. let mut chunk_index_be64 = vec![0u8; 8]; write_be_u64(&mut chunk_index_be64, self.chunk_index); diff --git a/openpgp/src/crypto/backend/nettle.rs b/openpgp/src/crypto/backend/nettle.rs index 7bbea8ca..73b37569 100644 --- a/openpgp/src/crypto/backend/nettle.rs +++ b/openpgp/src/crypto/backend/nettle.rs @@ -2,6 +2,7 @@ use nettle::random::{Random, Yarrow}; +pub mod aead; pub mod asymmetric; pub mod ecdh; diff --git a/openpgp/src/crypto/backend/nettle/aead.rs b/openpgp/src/crypto/backend/nettle/aead.rs new file mode 100644 index 00000000..1614a20a --- /dev/null +++ b/openpgp/src/crypto/backend/nettle/aead.rs @@ -0,0 +1,62 @@ +//! Implementation of AEAD using Nettle cryptographic library. +use nettle::{aead, cipher}; + +use crate::{Error, Result}; + +use crate::crypto::aead::Aead; +use crate::types::{AEADAlgorithm, SymmetricAlgorithm}; + +impl<T: nettle::aead::Aead> Aead for T { + fn update(&mut self, ad: &[u8]) { + self.update(ad) + } + fn encrypt(&mut self, dst: &mut [u8], src: &[u8]) { + self.encrypt(dst, src) + } + fn decrypt(&mut self, dst: &mut [u8], src: &[u8]) { + self.decrypt(dst, src) + } + fn digest(&mut self, digest: &mut [u8]) { + self.digest(digest) + } + fn digest_size(&self) -> usize { + self.digest_size() + } +} + +impl AEADAlgorithm { + pub(crate) fn context( + &self, + sym_algo: SymmetricAlgorithm, + key: &[u8], + nonce: &[u8], + ) -> Result<Box<dyn Aead>> { + match self { + AEADAlgorithm::EAX => match sym_algo { + SymmetricAlgorithm::AES128 => Ok(Box::new( + aead::Eax::<cipher::Aes128>::with_key_and_nonce(key, nonce)?, + )), + SymmetricAlgorithm::AES192 => Ok(Box::new( + aead::Eax::<cipher::Aes192>::with_key_and_nonce(key, nonce)?, + )), + SymmetricAlgorithm::AES256 => Ok(Box::new( + aead::Eax::<cipher::Aes256>::with_key_and_nonce(key, nonce)?, + )), + SymmetricAlgorithm::Twofish => Ok(Box::new( + aead::Eax::<cipher::Twofish>::with_key_and_nonce(key, nonce)?, + )), + SymmetricAlgorithm::Camellia128 => Ok(Box::new( + aead::Eax::<cipher::Camellia128>::with_key_and_nonce(key, nonce)?, + )), + SymmetricAlgorithm::Camellia192 => Ok(Box::new( + aead::Eax::<cipher::Camellia192>::with_key_and_nonce(key, nonce)?, + )), + SymmetricAlgorithm::Camellia256 => Ok(Box::new( + aead::Eax::<cipher::Camellia256>::with_key_and_nonce(key, nonce)?, + )), + _ => Err(Error::UnsupportedSymmetricAlgorithm(sym_algo).into()), + }, + _ => Err(Error::UnsupportedAEADAlgorithm(self.clone()).into()), + } + } +} |