diff options
Diffstat (limited to 'vendor/hmac/src/optim.rs')
-rw-r--r-- | vendor/hmac/src/optim.rs | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/vendor/hmac/src/optim.rs b/vendor/hmac/src/optim.rs new file mode 100644 index 0000000..32d6277 --- /dev/null +++ b/vendor/hmac/src/optim.rs @@ -0,0 +1,280 @@ +use super::{get_der_key, IPAD, OPAD}; +use core::{fmt, slice}; +#[cfg(feature = "reset")] +use digest::Reset; +use digest::{ + block_buffer::Eager, + core_api::{ + AlgorithmName, Block, BlockSizeUser, Buffer, BufferKindUser, CoreProxy, CoreWrapper, + FixedOutputCore, OutputSizeUser, UpdateCore, + }, + crypto_common::{Key, KeySizeUser}, + generic_array::typenum::{IsLess, Le, NonZero, U256}, + HashMarker, InvalidLength, KeyInit, MacMarker, Output, +}; + +/// Generic HMAC instance. +pub type Hmac<D> = CoreWrapper<HmacCore<D>>; + +/// Generic core HMAC instance, which operates over blocks. +pub struct HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + digest: D::Core, + opad_digest: D::Core, + #[cfg(feature = "reset")] + ipad_digest: D::Core, +} + +impl<D> Clone for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + fn clone(&self) -> Self { + Self { + digest: self.digest.clone(), + opad_digest: self.opad_digest.clone(), + #[cfg(feature = "reset")] + ipad_digest: self.ipad_digest.clone(), + } + } +} + +impl<D> MacMarker for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ +} + +impl<D> BufferKindUser for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + type BufferKind = Eager; +} + +impl<D> KeySizeUser for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + type KeySize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize; +} + +impl<D> BlockSizeUser for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + type BlockSize = <<D as CoreProxy>::Core as BlockSizeUser>::BlockSize; +} + +impl<D> OutputSizeUser for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + type OutputSize = <<D as CoreProxy>::Core as OutputSizeUser>::OutputSize; +} + +impl<D> KeyInit for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + #[inline(always)] + fn new(key: &Key<Self>) -> Self { + Self::new_from_slice(key.as_slice()).unwrap() + } + + #[inline(always)] + fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> { + let mut buf = get_der_key::<CoreWrapper<D::Core>>(key); + for b in buf.iter_mut() { + *b ^= IPAD; + } + let mut digest = D::Core::default(); + digest.update_blocks(slice::from_ref(&buf)); + + for b in buf.iter_mut() { + *b ^= IPAD ^ OPAD; + } + + let mut opad_digest = D::Core::default(); + opad_digest.update_blocks(slice::from_ref(&buf)); + + Ok(Self { + #[cfg(feature = "reset")] + ipad_digest: digest.clone(), + opad_digest, + digest, + }) + } +} + +impl<D> UpdateCore for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + #[inline(always)] + fn update_blocks(&mut self, blocks: &[Block<Self>]) { + self.digest.update_blocks(blocks); + } +} + +impl<D> FixedOutputCore for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + #[inline(always)] + fn finalize_fixed_core(&mut self, buffer: &mut Buffer<Self>, out: &mut Output<Self>) { + let mut hash = Output::<D::Core>::default(); + self.digest.finalize_fixed_core(buffer, &mut hash); + // finalize_fixed_core should reset the buffer as well, but + // to be extra safe we reset it explicitly again. + buffer.reset(); + #[cfg(not(feature = "reset"))] + let h = &mut self.opad_digest; + #[cfg(feature = "reset")] + let mut h = self.opad_digest.clone(); + buffer.digest_blocks(&hash, |b| h.update_blocks(b)); + h.finalize_fixed_core(buffer, out); + } +} + +#[cfg(feature = "reset")] +#[cfg_attr(docsrs, doc(cfg(feature = "reset")))] +impl<D> Reset for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + #[inline(always)] + fn reset(&mut self) { + self.digest = self.ipad_digest.clone(); + } +} + +impl<D> AlgorithmName for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + AlgorithmName + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Hmac<")?; + <D::Core as AlgorithmName>::write_alg_name(f)?; + f.write_str(">") + } +} + +impl<D> fmt::Debug for HmacCore<D> +where + D: CoreProxy, + D::Core: HashMarker + + AlgorithmName + + UpdateCore + + FixedOutputCore + + BufferKindUser<BufferKind = Eager> + + Default + + Clone, + <D::Core as BlockSizeUser>::BlockSize: IsLess<U256>, + Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("HmacCore<")?; + <D::Core as AlgorithmName>::write_alg_name(f)?; + f.write_str("> { ... }") + } +} |