diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2022-02-15 12:43:38 +0100 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2022-02-15 14:02:14 +0100 |
commit | 579113cd358d873f75b61a5688e86e934d04baa5 (patch) | |
tree | df0b8c7ceb967c6c4eb9572ee331b57b42bb50c1 /openpgp/src/crypto/backend | |
parent | 8d60d90ce8200c91ca5f0123f66ed645f3321c7b (diff) |
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.
Diffstat (limited to 'openpgp/src/crypto/backend')
-rw-r--r-- | openpgp/src/crypto/backend/cng/aead.rs | 35 | ||||
-rw-r--r-- | 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<T, N: ArrayLength<T>> { const LEN: usize; + + /// Like [`GenericArray::from_slice`], but fallible. + fn try_from_slice(slice: &[T]) -> Result<&GenericArray<T, N>> { + 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<T, N: ArrayLength<T>> GenericArrayExt for GenericArray<T, N> { +impl<T, N: ArrayLength<T>> GenericArrayExt<T, N> for GenericArray<T, N> { 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::<BlockCipherKey<Aes, U128>, 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::<BlockCipherKey<Aes, U192>, 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::<BlockCipherKey<Aes, U256>, 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 { <eax::Tag as GenericArrayExt>::LEN } + fn digest_size(&self) -> usize { + <eax::Tag as GenericArrayExt<_, _>>::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 { <eax::Tag as GenericArrayExt>::LEN } + fn digest_size(&self) -> usize { + <eax::Tag as GenericArrayExt<_, _>>::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<T, N: ArrayLength<T>> { const LEN: usize; + + /// Like [`GenericArray::from_slice`], but fallible. + fn try_from_slice(slice: &[T]) -> Result<&GenericArray<T, N>> { + 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<T, N: ArrayLength<T>> GenericArrayExt for GenericArray<T, N> { +impl<T, N: ArrayLength<T>> GenericArrayExt<T, N> for GenericArray<T, N> { 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::<aes::Aes128, Encrypt>::with_key_and_nonce(key.into(), nonce.into()))), + 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(key.into(), nonce.into()))), + Eax::<aes::Aes128, Decrypt>::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), } SymmetricAlgorithm::AES192 => match op { CipherOp::Encrypt => Ok(Box::new( - Eax::<aes::Aes192, Encrypt>::with_key_and_nonce(key.into(), nonce.into()))), + 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(key.into(), nonce.into()))), + Eax::<aes::Aes192, Decrypt>::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), } SymmetricAlgorithm::AES256 => match op { CipherOp::Encrypt => Ok(Box::new( - Eax::<aes::Aes256, Encrypt>::with_key_and_nonce(key.into(), nonce.into()))), + 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(key.into(), nonce.into()))), + Eax::<aes::Aes256, Decrypt>::with_key_and_nonce( + GenericArray::try_from_slice(key)?, + GenericArray::try_from_slice(nonce)?))), } | SymmetricAlgorithm::IDEA | SymmetricAlgorithm::TripleDES |