summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustus Winter <justus@sequoia-pgp.org>2022-02-15 12:43:38 +0100
committerJustus Winter <justus@sequoia-pgp.org>2022-02-15 14:02:14 +0100
commit579113cd358d873f75b61a5688e86e934d04baa5 (patch)
treedf0b8c7ceb967c6c4eb9572ee331b57b42bb50c1
parent8d60d90ce8200c91ca5f0123f66ed645f3321c7b (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.
-rw-r--r--openpgp/src/crypto/backend/cng/aead.rs35
-rw-r--r--openpgp/src/crypto/backend/rust/aead.rs39
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