summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2023-02-28 12:19:05 +0100
committerJustus Winter <justus@sequoia-pgp.org>2023-02-28 13:20:22 +0100
commitf6b4b029930ac93fd6b3efed0128940b4b343fe0 (patch)
treeefefee6c5e48723bfe1b10d6ce179aef478eeac5
parent39bf91d6812f499327752803a6ecfada74a9b606 (diff)
openpgp: Further simplify AEAD abstraction.
- Hand in the additional authenticated data when constructing the context.
-rw-r--r--openpgp/src/crypto/aead.rs51
-rw-r--r--openpgp/src/crypto/backend/cng/aead.rs105
-rw-r--r--openpgp/src/crypto/backend/nettle/aead.rs70
-rw-r--r--openpgp/src/crypto/backend/openssl/aead.rs7
-rw-r--r--openpgp/src/crypto/backend/rust/aead.rs89
-rw-r--r--openpgp/src/packet/skesk.rs16
6 files changed, 178 insertions, 160 deletions
diff --git a/openpgp/src/crypto/aead.rs b/openpgp/src/crypto/aead.rs
index 7b9dc3fb..feee035f 100644
--- a/openpgp/src/crypto/aead.rs
+++ b/openpgp/src/crypto/aead.rs
@@ -50,9 +50,6 @@ pub(crate) fn chunk_size_usize(chunk_size: u64) -> Result<usize> {
///
/// [sealed]: https://rust-lang.github.io/api-guidelines/future-proofing.html#sealed-traits-protect-against-downstream-implementations-c-sealed
pub trait Aead : seal::Sealed {
- /// Adds associated data `ad`.
- fn update(&mut self, ad: &[u8]) -> Result<()>;
-
/// Encrypts one chunk `src` to `dst` adding a digest.
///
/// Note: `dst` must be large enough to accommodate both the
@@ -387,13 +384,9 @@ impl<'a, S: Schedule> Decryptor<'a, S> {
let mut aead = self.schedule.next_chunk(
self.chunk_index,
|iv, ad| {
- self.aead.context(self.sym_algo, &self.key, iv,
+ self.aead.context(self.sym_algo, &self.key, ad, iv,
CipherOp::Decrypt)
- .map(|mut aead| {
- aead.update(ad)?;
- Ok::<Box<dyn Aead>, anyhow::Error>(aead)
- })
- })??;
+ })?;
// Decrypt the chunk and check the tag.
let to_decrypt = chunk.len() - self.digest_size;
@@ -438,13 +431,9 @@ impl<'a, S: Schedule> Decryptor<'a, S> {
let mut aead = self.schedule.final_chunk(
self.chunk_index, self.bytes_decrypted,
|iv, ad| {
- self.aead.context(self.sym_algo, &self.key, iv,
+ self.aead.context(self.sym_algo, &self.key, ad, iv,
CipherOp::Decrypt)
- .map(|mut aead| {
- aead.update(ad)?;
- Ok::<Box<dyn Aead>, anyhow::Error>(aead)
- })
- })??;
+ })?;
let final_digest = self.source.data(final_digest_size)?;
@@ -656,13 +645,9 @@ impl<W: io::Write, S: Schedule> Encryptor<W, S> {
if self.buffer.len() == self.chunk_size {
let mut aead =
self.schedule.next_chunk(self.chunk_index, |iv, ad| {
- self.aead.context(self.sym_algo, &self.key, iv,
+ self.aead.context(self.sym_algo, &self.key, ad, iv,
CipherOp::Encrypt)
- .map(|mut aead| {
- aead.update(ad)?;
- Ok::<Box<dyn Aead>, anyhow::Error>(aead)
- })
- })??;
+ })?;
let inner = self.inner.as_mut().unwrap();
@@ -682,13 +667,9 @@ impl<W: io::Write, S: Schedule> Encryptor<W, S> {
// Complete chunk.
let mut aead =
self.schedule.next_chunk(self.chunk_index, |iv, ad| {
- self.aead.context(self.sym_algo, &self.key, iv,
+ self.aead.context(self.sym_algo, &self.key, ad, iv,
CipherOp::Encrypt)
- .map(|mut aead| {
- aead.update(ad)?;
- Ok::<Box<dyn Aead>, anyhow::Error>(aead)
- })
- })??;
+ })?;
let inner = self.inner.as_mut().unwrap();
@@ -713,13 +694,9 @@ impl<W: io::Write, S: Schedule> Encryptor<W, S> {
if !self.buffer.is_empty() {
let mut aead =
self.schedule.next_chunk(self.chunk_index, |iv, ad| {
- self.aead.context(self.sym_algo, &self.key, iv,
+ self.aead.context(self.sym_algo, &self.key, ad, iv,
CipherOp::Encrypt)
- .map(|mut aead| {
- aead.update(ad)?;
- Ok::<Box<dyn Aead>, anyhow::Error>(aead)
- })
- })??;
+ })?;
// Encrypt the chunk.
unsafe {
@@ -741,13 +718,9 @@ impl<W: io::Write, S: Schedule> Encryptor<W, S> {
let mut aead = self.schedule.final_chunk(
self.chunk_index, self.bytes_encrypted,
|iv, ad| {
- self.aead.context(self.sym_algo, &self.key, iv,
+ self.aead.context(self.sym_algo, &self.key, ad, iv,
CipherOp::Encrypt)
- .map(|mut aead| {
- aead.update(ad)?;
- Ok::<Box<dyn Aead>, anyhow::Error>(aead)
- })
- })??;
+ })?;
aead.encrypt_seal(&mut self.scratch[..self.digest_size], b"")?;
inner.write_all(&self.scratch[..self.digest_size])?;
diff --git a/openpgp/src/crypto/backend/cng/aead.rs b/openpgp/src/crypto/backend/cng/aead.rs
index afc6b7c9..c714efbb 100644
--- a/openpgp/src/crypto/backend/cng/aead.rs
+++ b/openpgp/src/crypto/backend/cng/aead.rs
@@ -7,7 +7,7 @@ use crate::crypto::mem::secure_cmp;
use crate::seal;
use crate::types::{AEADAlgorithm, SymmetricAlgorithm};
-use eax::online::{EaxOnline, Encrypt, Decrypt};
+use eax::online::{Eax, Encrypt, Decrypt};
use win_crypto_ng::symmetric::{BlockCipherKey, Aes};
use win_crypto_ng::symmetric::block_cipher::generic_array::{GenericArray, ArrayLength};
use win_crypto_ng::symmetric::block_cipher::generic_array::typenum::{U128, U192, U256};
@@ -42,42 +42,67 @@ impl AEADAlgorithm {
&self,
sym_algo: SymmetricAlgorithm,
key: &[u8],
+ aad: &[u8],
nonce: &[u8],
op: CipherOp,
) -> Result<Box<dyn Aead>> {
match self {
AEADAlgorithm::EAX => match sym_algo {
- | SymmetricAlgorithm::AES128 => {
- let key = GenericArray::try_from_slice(key)?;
- let nonce = GenericArray::try_from_slice(nonce)?;
- Ok(match op {
- CipherOp::Encrypt =>
- Box::new(EaxOnline::<BlockCipherKey<Aes, U128>, Encrypt>::with_key_and_nonce(key, nonce)),
- CipherOp::Decrypt =>
- Box::new(EaxOnline::<BlockCipherKey<Aes, U128>, Decrypt>::with_key_and_nonce(key, nonce)),
- })
- }
- SymmetricAlgorithm::AES192 => {
- let key = GenericArray::try_from_slice(key)?;
- let nonce = GenericArray::try_from_slice(nonce)?;
- Ok(match op {
- CipherOp::Encrypt =>
- Box::new(EaxOnline::<BlockCipherKey<Aes, U192>, Encrypt>::with_key_and_nonce(key, nonce)),
- CipherOp::Decrypt =>
- Box::new(EaxOnline::<BlockCipherKey<Aes, U192>, Decrypt>::with_key_and_nonce(key, nonce)),
- })
- }
- SymmetricAlgorithm::AES256 => {
- let key = GenericArray::try_from_slice(key)?;
- let nonce = GenericArray::try_from_slice(nonce)?;
- Ok(match op {
- CipherOp::Encrypt =>
- Box::new(EaxOnline::<BlockCipherKey<Aes, U256>, Encrypt>::with_key_and_nonce(key, nonce)),
- CipherOp::Decrypt =>
- Box::new(EaxOnline::<BlockCipherKey<Aes, U256>, Decrypt>::with_key_and_nonce(key, nonce)),
- })
- }
+ SymmetricAlgorithm::AES128 => match op {
+ CipherOp::Encrypt => {
+ let mut ctx =
+ Eax::<BlockCipherKey<Aes, U128>, Encrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ CipherOp::Decrypt => {
+ let mut ctx =
+ Eax::<BlockCipherKey<Aes, U128>, Decrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ },
+ SymmetricAlgorithm::AES192 => match op {
+ CipherOp::Encrypt => {
+ let mut ctx =
+ Eax::<BlockCipherKey<Aes, U192>, Encrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ CipherOp::Decrypt => {
+ let mut ctx =
+ Eax::<BlockCipherKey<Aes, U192>, Decrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ },
+ SymmetricAlgorithm::AES256 => match op {
+ CipherOp::Encrypt => {
+ let mut ctx =
+ Eax::<BlockCipherKey<Aes, U256>, Encrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ CipherOp::Decrypt => {
+ let mut ctx =
+ Eax::<BlockCipherKey<Aes, U256>, Decrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ },
_ => Err(Error::UnsupportedSymmetricAlgorithm(sym_algo).into()),
},
_ => Err(Error::UnsupportedAEADAlgorithm(self.clone()).into()),
@@ -88,11 +113,7 @@ impl AEADAlgorithm {
macro_rules! impl_aead {
($($type: ty),*) => {
$(
- impl Aead for EaxOnline<$type, Encrypt> {
- fn update(&mut self, ad: &[u8]) -> Result<()> {
- self.update_assoc(ad);
- Ok(())
- }
+ impl Aead for Eax<$type, Encrypt> {
fn digest_size(&self) -> usize {
<eax::Tag as GenericArrayExt<_, _>>::LEN
}
@@ -100,7 +121,7 @@ macro_rules! impl_aead {
debug_assert_eq!(dst.len(), src.len() + self.digest_size());
let len = core::cmp::min(dst.len(), src.len());
dst[..len].copy_from_slice(&src[..len]);
- EaxOnline::<$type, Encrypt>::encrypt(self, &mut dst[..len]);
+ Eax::<$type, Encrypt>::encrypt(self, &mut dst[..len]);
let tag = self.tag_clone();
dst[src.len()..].copy_from_slice(&tag[..]);
@@ -110,14 +131,10 @@ macro_rules! impl_aead {
panic!("AEAD decryption called in the encryption context")
}
}
- impl seal::Sealed for EaxOnline<$type, Encrypt> {}
+ impl seal::Sealed for Eax<$type, Encrypt> {}
)*
$(
- impl Aead for EaxOnline<$type, Decrypt> {
- fn update(&mut self, ad: &[u8]) -> Result<()> {
- self.update_assoc(ad);
- Ok(())
- }
+ impl Aead for Eax<$type, Decrypt> {
fn digest_size(&self) -> usize {
<eax::Tag as GenericArrayExt<_, _>>::LEN
}
@@ -138,7 +155,7 @@ macro_rules! impl_aead {
Ok(())
}
}
- impl seal::Sealed for EaxOnline<$type, Decrypt> {}
+ impl seal::Sealed for Eax<$type, Decrypt> {}
)*
};
}
diff --git a/openpgp/src/crypto/backend/nettle/aead.rs b/openpgp/src/crypto/backend/nettle/aead.rs
index df2f0f64..ad6014d7 100644
--- a/openpgp/src/crypto/backend/nettle/aead.rs
+++ b/openpgp/src/crypto/backend/nettle/aead.rs
@@ -1,7 +1,7 @@
//! Implementation of AEAD using Nettle cryptographic library.
use std::cmp::Ordering;
-use nettle::{aead, cipher};
+use nettle::{aead::{self, Aead as _}, cipher};
use crate::{Error, Result};
@@ -18,10 +18,6 @@ const DANGER_DISABLE_AUTHENTICATION: bool = false;
impl<T: nettle::aead::Aead> seal::Sealed for T {}
impl<T: nettle::aead::Aead> Aead for T {
- fn update(&mut self, ad: &[u8]) -> Result<()> {
- self.update(ad);
- Ok(())
- }
fn encrypt_seal(&mut self, dst: &mut [u8], src: &[u8]) -> Result<()> {
debug_assert_eq!(dst.len(), src.len() + self.digest_size());
self.encrypt(dst, src);
@@ -50,32 +46,54 @@ impl AEADAlgorithm {
&self,
sym_algo: SymmetricAlgorithm,
key: &[u8],
+ aad: &[u8],
nonce: &[u8],
_op: CipherOp,
) -> 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)?,
- )),
+ SymmetricAlgorithm::AES128 => {
+ let mut ctx =
+ aead::Eax::<cipher::Aes128>::with_key_and_nonce(key, nonce)?;
+ ctx.update(aad);
+ Ok(Box::new(ctx))
+ },
+ SymmetricAlgorithm::AES192 => {
+ let mut ctx =
+ aead::Eax::<cipher::Aes192>::with_key_and_nonce(key, nonce)?;
+ ctx.update(aad);
+ Ok(Box::new(ctx))
+ },
+ SymmetricAlgorithm::AES256 => {
+ let mut ctx =
+ aead::Eax::<cipher::Aes256>::with_key_and_nonce(key, nonce)?;
+ ctx.update(aad);
+ Ok(Box::new(ctx))
+ },
+ SymmetricAlgorithm::Twofish => {
+ let mut ctx =
+ aead::Eax::<cipher::Twofish>::with_key_and_nonce(key, nonce)?;
+ ctx.update(aad);
+ Ok(Box::new(ctx))
+ },
+ SymmetricAlgorithm::Camellia128 => {
+ let mut ctx =
+ aead::Eax::<cipher::Camellia128>::with_key_and_nonce(key, nonce)?;
+ ctx.update(aad);
+ Ok(Box::new(ctx))
+ },
+ SymmetricAlgorithm::Camellia192 => {
+ let mut ctx =
+ aead::Eax::<cipher::Camellia192>::with_key_and_nonce(key, nonce)?;
+ ctx.update(aad);
+ Ok(Box::new(ctx))
+ },
+ SymmetricAlgorithm::Camellia256 => {
+ let mut ctx =
+ aead::Eax::<cipher::Camellia256>::with_key_and_nonce(key, nonce)?;
+ ctx.update(aad);
+ Ok(Box::new(ctx))
+ },
_ => Err(Error::UnsupportedSymmetricAlgorithm(sym_algo).into()),
},
_ => Err(Error::UnsupportedAEADAlgorithm(*self).into()),
diff --git a/openpgp/src/crypto/backend/openssl/aead.rs b/openpgp/src/crypto/backend/openssl/aead.rs
index 5e73ff0a..469539c0 100644
--- a/openpgp/src/crypto/backend/openssl/aead.rs
+++ b/openpgp/src/crypto/backend/openssl/aead.rs
@@ -13,11 +13,6 @@ struct OpenSslContext {
}
impl Aead for OpenSslContext {
- fn update(&mut self, ad: &[u8]) -> Result<()> {
- self.ctx.cipher_update(ad, None)?;
- Ok(())
- }
-
fn encrypt_seal(&mut self, dst: &mut [u8], src: &[u8]) -> Result<()> {
debug_assert_eq!(dst.len(), src.len() + self.digest_size());
@@ -59,6 +54,7 @@ impl AEADAlgorithm {
&self,
sym_algo: SymmetricAlgorithm,
key: &[u8],
+ aad: &[u8],
nonce: &[u8],
op: CipherOp,
) -> Result<Box<dyn Aead>> {
@@ -89,6 +85,7 @@ impl AEADAlgorithm {
ctx.decrypt_init(None, None, Some(nonce))?,
}
ctx.set_padding(false);
+ ctx.cipher_update(aad, None)?;
Ok(Box::new(OpenSslContext {
ctx,
}))
diff --git a/openpgp/src/crypto/backend/rust/aead.rs b/openpgp/src/crypto/backend/rust/aead.rs
index 5c57e79a..1e4ca4c0 100644
--- a/openpgp/src/crypto/backend/rust/aead.rs
+++ b/openpgp/src/crypto/backend/rust/aead.rs
@@ -45,11 +45,6 @@ where
Cipher: BlockCipher<BlockSize = U16> + NewBlockCipher + Clone,
Cipher::ParBlocks: ArrayLength<Block<Cipher>>,
{
- fn update(&mut self, ad: &[u8]) -> Result<()> {
- self.update_assoc(ad);
- Ok(())
- }
-
fn digest_size(&self) -> usize {
eax::Tag::LEN
}
@@ -74,11 +69,6 @@ where
Cipher: BlockCipher<BlockSize = U16> + NewBlockCipher + Clone,
Cipher::ParBlocks: ArrayLength<Block<Cipher>>,
{
- fn update(&mut self, ad: &[u8]) -> Result<()> {
- self.update_assoc(ad);
- Ok(())
- }
-
fn digest_size(&self) -> usize {
eax::Tag::LEN
}
@@ -114,41 +104,66 @@ impl AEADAlgorithm {
&self,
sym_algo: SymmetricAlgorithm,
key: &[u8],
+ aad: &[u8],
nonce: &[u8],
op: CipherOp,
) -> Result<Box<dyn Aead>> {
match self {
AEADAlgorithm::EAX => match sym_algo {
SymmetricAlgorithm::AES128 => match op {
- CipherOp::Encrypt => Ok(Box::new(
- Eax::<aes::Aes128, Encrypt>::with_key_and_nonce(
- GenericArray::try_from_slice(key)?,
- GenericArray::try_from_slice(nonce)?))),
- CipherOp::Decrypt => Ok(Box::new(
- Eax::<aes::Aes128, Decrypt>::with_key_and_nonce(
- GenericArray::try_from_slice(key)?,
- GenericArray::try_from_slice(nonce)?))),
- }
+ CipherOp::Encrypt => {
+ let mut ctx =
+ Eax::<aes::Aes128, Encrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ CipherOp::Decrypt => {
+ let mut ctx =
+ Eax::<aes::Aes128, Decrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ },
SymmetricAlgorithm::AES192 => match op {
- CipherOp::Encrypt => Ok(Box::new(
- Eax::<aes::Aes192, Encrypt>::with_key_and_nonce(
- GenericArray::try_from_slice(key)?,
- GenericArray::try_from_slice(nonce)?))),
- CipherOp::Decrypt => Ok(Box::new(
- Eax::<aes::Aes192, Decrypt>::with_key_and_nonce(
- GenericArray::try_from_slice(key)?,
- GenericArray::try_from_slice(nonce)?))),
- }
+ CipherOp::Encrypt => {
+ let mut ctx =
+ Eax::<aes::Aes192, Encrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ CipherOp::Decrypt => {
+ let mut ctx =
+ Eax::<aes::Aes192, Decrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ },
SymmetricAlgorithm::AES256 => match op {
- CipherOp::Encrypt => Ok(Box::new(
- Eax::<aes::Aes256, Encrypt>::with_key_and_nonce(
- GenericArray::try_from_slice(key)?,
- GenericArray::try_from_slice(nonce)?))),
- CipherOp::Decrypt => Ok(Box::new(
- Eax::<aes::Aes256, Decrypt>::with_key_and_nonce(
- GenericArray::try_from_slice(key)?,
- GenericArray::try_from_slice(nonce)?))),
- }
+ CipherOp::Encrypt => {
+ let mut ctx =
+ Eax::<aes::Aes256, Encrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ CipherOp::Decrypt => {
+ let mut ctx =
+ Eax::<aes::Aes256, Decrypt>::with_key_and_nonce(
+ GenericArray::try_from_slice(key)?,
+ GenericArray::try_from_slice(nonce)?);
+ ctx.update_assoc(aad);
+ Ok(Box::new(ctx))
+ },
+ },
| SymmetricAlgorithm::IDEA
| SymmetricAlgorithm::TripleDES
| SymmetricAlgorithm::CAST5
diff --git a/openpgp/src/packet/skesk.rs b/openpgp/src/packet/skesk.rs
index 694f7496..782511bb 100644
--- a/openpgp/src/packet/skesk.rs
+++ b/openpgp/src/packet/skesk.rs
@@ -458,11 +458,9 @@ impl SKESK5 {
let key = s2k.derive_key(password, esk_algo.key_size()?)?;
let mut iv = vec![0u8; esk_aead.nonce_size()?];
crypto::random(&mut iv);
- let mut ctx = esk_aead.context(esk_algo, &key, &iv, CipherOp::Encrypt)?;
-
- // Prepare associated data.
- let ad = [0xc3, 5, esk_algo.into(), esk_aead.into()];
- ctx.update(&ad)?;
+ let aad = [0xc3, 5, esk_algo.into(), esk_aead.into()];
+ let mut ctx = esk_aead.context(esk_algo, &key, &aad, &iv,
+ CipherOp::Encrypt)?;
// Encrypt the session key with the KEK.
let mut esk_digest =
@@ -497,12 +495,12 @@ impl SKESK5 {
if let Some(esk) = self.esk()? {
// Use the derived key to decrypt the ESK.
+ let aad = [0xc3, 5 /* Version. */, self.symmetric_algo().into(),
+ self.aead_algo.into()];
let mut cipher = self.aead_algo.context(
- self.symmetric_algo(), &key, self.aead_iv()?, CipherOp::Decrypt)?;
+ self.symmetric_algo(), &key, &aad, self.aead_iv()?,
+ CipherOp::Decrypt)?;
- let ad = [0xc3, 5 /* Version. */, self.symmetric_algo().into(),
- self.aead_algo.into()];
- cipher.update(&ad)?;
let mut plain: SessionKey = vec![0; esk.len()].into();
cipher.decrypt_verify(&mut plain, esk, &self.aead_digest[..])?;
Ok((SymmetricAlgorithm::Unencrypted, plain))