diff --git a/crypto-common/src/lib.rs b/crypto-common/src/lib.rs index bb6d4758e..6349c61f3 100644 --- a/crypto-common/src/lib.rs +++ b/crypto-common/src/lib.rs @@ -153,7 +153,7 @@ pub trait AlgorithmName { fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result; } -/// Types which can be initialized from key. +/// Types which can be initialized from a key. pub trait KeyInit: KeySizeUser + Sized { /// Create new value from fixed size key. fn new(key: &Key) -> Self; @@ -209,7 +209,7 @@ pub trait KeyInit: KeySizeUser + Sized { } } -/// Types which can be initialized from key and initialization vector (nonce). +/// Types which can be initialized from a key and initialization vector (nonce). pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { /// Create new value from fixed length key and nonce. fn new(key: &Key, iv: &Iv) -> Self; @@ -323,6 +323,27 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized { } } +/// Types which can be fallibly initialized from a key. +pub trait TryKeyInit: KeySizeUser + Sized { + /// Create new value from a fixed-size key. + /// + /// # Errors + /// - if the key is considered invalid according to rules specific to the implementing type + fn new(key: &Key) -> Result; + + /// Create new value from a variable size key. + /// + /// # Errors + /// - if the provided slice is the wrong length + /// - if the key is considered invalid by [`TryKeyInit::new`] + #[inline] + fn new_from_slice(key: &[u8]) -> Result { + <&Key>::try_from(key) + .map_err(|_| InvalidKey) + .and_then(Self::new) + } +} + /// Types which can be initialized from another type (usually block ciphers). /// /// Usually used for initializing types from block ciphers. @@ -462,6 +483,20 @@ where } */ +/// Error type for [`TryKeyInit`] for cases where the provided bytes do not correspond to a +/// valid key. +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub struct InvalidKey; + +impl fmt::Display for InvalidKey { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + f.write_str("WeakKey") + } +} + +impl core::error::Error for InvalidKey {} + /// The error type returned when key and/or IV used in the [`KeyInit`], /// [`KeyIvInit`], and [`InnerIvInit`] slice-based methods had /// an invalid length.