From 579113cd358d873f75b61a5688e86e934d04baa5 Mon Sep 17 00:00:00 2001 From: Justus Winter Date: Tue, 15 Feb 2022 12:43:38 +0100 Subject: openpgp: Fallible conversion to GenericArray references. - The former commit fixes a crash that should never have happened: with a fallible conversion to GenericArrays, the error can be handled at runtime. - Unfortunately, the upstream crate does not offer a convenient fallible conversion. Implement and use it. --- openpgp/src/crypto/backend/cng/aead.rs | 35 ++++++++++++++++++++--------- openpgp/src/crypto/backend/rust/aead.rs | 39 ++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/openpgp/src/crypto/backend/cng/aead.rs b/openpgp/src/crypto/backend/cng/aead.rs index aaa9c854..a7b87613 100644 --- a/openpgp/src/crypto/backend/cng/aead.rs +++ b/openpgp/src/crypto/backend/cng/aead.rs @@ -10,11 +10,22 @@ 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}; -trait GenericArrayExt { +trait GenericArrayExt> { const LEN: usize; + + /// Like [`GenericArray::from_slice`], but fallible. + fn try_from_slice(slice: &[T]) -> Result<&GenericArray> { + if slice.len() == Self::LEN { + Ok(GenericArray::from_slice(slice)) + } else { + Err(Error::InvalidArgument( + format!("Invalid slice length, want {}, got {}", + Self::LEN, slice.len())).into()) + } + } } -impl> GenericArrayExt for GenericArray { +impl> GenericArrayExt for GenericArray { const LEN: usize = N::USIZE; } @@ -30,8 +41,8 @@ impl AEADAlgorithm { match self { AEADAlgorithm::EAX => match sym_algo { | SymmetricAlgorithm::AES128 => { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); + let key = GenericArray::try_from_slice(key)?; + let nonce = GenericArray::try_from_slice(nonce)?; Ok(match op { CipherOp::Encrypt => Box::new(EaxOnline::, Encrypt>::with_key_and_nonce(key, nonce)), @@ -40,8 +51,8 @@ impl AEADAlgorithm { }) } SymmetricAlgorithm::AES192 => { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); + let key = GenericArray::try_from_slice(key)?; + let nonce = GenericArray::try_from_slice(nonce)?; Ok(match op { CipherOp::Encrypt => Box::new(EaxOnline::, Encrypt>::with_key_and_nonce(key, nonce)), @@ -50,8 +61,8 @@ impl AEADAlgorithm { }) } SymmetricAlgorithm::AES256 => { - let key = GenericArray::from_slice(key); - let nonce = GenericArray::from_slice(nonce); + let key = GenericArray::try_from_slice(key)?; + let nonce = GenericArray::try_from_slice(nonce)?; Ok(match op { CipherOp::Encrypt => Box::new(EaxOnline::, Encrypt>::with_key_and_nonce(key, nonce)), @@ -71,7 +82,9 @@ macro_rules! impl_aead { $( impl Aead for EaxOnline<$type, Encrypt> { fn update(&mut self, ad: &[u8]) { self.update_assoc(ad) } - fn digest_size(&self) -> usize { ::LEN } + fn digest_size(&self) -> usize { + >::LEN + } fn digest(&mut self, digest: &mut [u8]) { let tag = self.tag_clone(); digest[..tag.len()].copy_from_slice(&tag[..]); @@ -90,7 +103,9 @@ macro_rules! impl_aead { $( impl Aead for EaxOnline<$type, Decrypt> { fn update(&mut self, ad: &[u8]) { self.update_assoc(ad) } - fn digest_size(&self) -> usize { ::LEN } + fn digest_size(&self) -> usize { + >::LEN + } fn digest(&mut self, digest: &mut [u8]) { let tag = self.tag_clone(); digest[..tag.len()].copy_from_slice(&tag[..]); diff --git a/openpgp/src/crypto/backend/rust/aead.rs b/openpgp/src/crypto/backend/rust/aead.rs index ab2ca208..e5fcdb0b 100644 --- a/openpgp/src/crypto/backend/rust/aead.rs +++ b/openpgp/src/crypto/backend/rust/aead.rs @@ -13,11 +13,22 @@ use crate::crypto::aead::{Aead, CipherOp}; use crate::seal; use crate::types::{AEADAlgorithm, SymmetricAlgorithm}; -trait GenericArrayExt { +trait GenericArrayExt> { const LEN: usize; + + /// Like [`GenericArray::from_slice`], but fallible. + fn try_from_slice(slice: &[T]) -> Result<&GenericArray> { + if slice.len() == Self::LEN { + Ok(GenericArray::from_slice(slice)) + } else { + Err(Error::InvalidArgument( + format!("Invalid slice length, want {}, got {}", + Self::LEN, slice.len())).into()) + } + } } -impl> GenericArrayExt for GenericArray { +impl> GenericArrayExt for GenericArray { const LEN: usize = N::USIZE; } @@ -98,21 +109,33 @@ impl AEADAlgorithm { AEADAlgorithm::EAX => match sym_algo { SymmetricAlgorithm::AES128 => match op { CipherOp::Encrypt => Ok(Box::new( - Eax::::with_key_and_nonce(key.into(), nonce.into()))), + Eax::::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), CipherOp::Decrypt => Ok(Box::new( - Eax::::with_key_and_nonce(key.into(), nonce.into()))), + Eax::::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), } SymmetricAlgorithm::AES192 => match op { CipherOp::Encrypt => Ok(Box::new( - Eax::::with_key_and_nonce(key.into(), nonce.into()))), + Eax::::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), CipherOp::Decrypt => Ok(Box::new( - Eax::::with_key_and_nonce(key.into(), nonce.into()))), + Eax::::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), } SymmetricAlgorithm::AES256 => match op { CipherOp::Encrypt => Ok(Box::new( - Eax::::with_key_and_nonce(key.into(), nonce.into()))), + Eax::::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), CipherOp::Decrypt => Ok(Box::new( - Eax::::with_key_and_nonce(key.into(), nonce.into()))), + Eax::::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), } | SymmetricAlgorithm::IDEA | SymmetricAlgorithm::TripleDES -- cgit v1.2.3