summaryrefslogtreecommitdiffstats
path: root/openpgp/src
diff options
context:
space:
mode:
authorIgor Matuszewski <igor@sequoia-pgp.org>2020-04-10 00:53:35 +0200
committerIgor Matuszewski <igor@sequoia-pgp.org>2020-06-22 11:57:07 +0200
commitc8c207e931f204e5746eaff7dd57382048d26492 (patch)
tree1482b26870f6f2cd54395255f5443ce1c25dc5a5 /openpgp/src
parentf30cc7f367084fa295bd542cf9eb9a3398657fce (diff)
openpgp: Move Nettle AEAD implementation to the backend module
Diffstat (limited to 'openpgp/src')
-rw-r--r--openpgp/src/crypto/aead.rs75
-rw-r--r--openpgp/src/crypto/backend/nettle.rs1
-rw-r--r--openpgp/src/crypto/backend/nettle/aead.rs62
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()),
+ }
+ }
+}