From d6d345207530ec3232d937aeee3b0c9255b33129 Mon Sep 17 00:00:00 2001 From: Andreas Grois Date: Sun, 9 Oct 2022 14:00:38 +0200 Subject: Also add url_parsing to this crate. --- src/passwordmaker/hmac.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/passwordmaker/hmac.rs (limited to 'src/passwordmaker/hmac.rs') diff --git a/src/passwordmaker/hmac.rs b/src/passwordmaker/hmac.rs new file mode 100644 index 0000000..4c9d6aa --- /dev/null +++ b/src/passwordmaker/hmac.rs @@ -0,0 +1,58 @@ +use crate::Hasher; + +pub(super) fn hmac(key : K, data : M) -> T::Output + where T : Hasher, + T::Output : AsRef<[u8]>, + K : Iterator + Clone, + M : Iterator, +{ + let key_len = key.clone().count(); + let key = if key_len > 64 { + KeyOrHash::from_hash(T::hash(&key.collect::>())) + } else { + KeyOrHash::from_key(key) + }; + let key = key.chain(std::iter::repeat(0)); //if key[i] does not exist, use 0 instead. + + let mut inner_pad = [0u8;64]; + let mut outer_pad = [0u8;64]; + + let pads = inner_pad.iter_mut().zip(outer_pad.iter_mut()); + for ((i,o),k) in pads.zip(key) { + *i = k ^ 0x36; + *o = k ^ 0x5C; + } + + let hash = T::hash(&inner_pad.iter().copied().chain(data).collect::>()); + T::hash(&outer_pad.iter().chain(hash.as_ref().iter()).copied().collect::>()) +} + +enum KeyOrHash, H: AsRef<[u8]>> { + Key(K), + Hash{ + hash : H, + idx : usize + } +} + +impl, H: AsRef<[u8]>> KeyOrHash{ + fn from_key(key : K) -> Self { + Self::Key(key) + } + fn from_hash(hash : H) -> Self { + Self::Hash { hash, idx: 0 } + } +} + +impl, H: AsRef<[u8]>> Iterator for KeyOrHash{ + type Item = u8; + fn next(&mut self) -> Option { + match self { + KeyOrHash::Key(k) => k.next(), + KeyOrHash::Hash { hash: owned, idx } => { + *idx += 1; + owned.as_ref().get(*idx-1).copied() + }, + } + } +} \ No newline at end of file -- cgit v1.2.3