diff options
author | Andreas Grois <andi@grois.info> | 2022-10-09 14:00:38 +0200 |
---|---|---|
committer | Andreas Grois <andi@grois.info> | 2022-10-09 14:00:38 +0200 |
commit | d6d345207530ec3232d937aeee3b0c9255b33129 (patch) | |
tree | 0645a54d0f695092ed6c0003777d2e212a99e5e5 /src/passwordmaker/hmac.rs | |
parent | 5e51b706d54a26470f33d1342f4666d5aab921fc (diff) |
Also add url_parsing to this crate.
Diffstat (limited to 'src/passwordmaker/hmac.rs')
-rw-r--r-- | src/passwordmaker/hmac.rs | 58 |
1 files changed, 58 insertions, 0 deletions
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<T, K, M>(key : K, data : M) -> T::Output + where T : Hasher, + T::Output : AsRef<[u8]>, + K : Iterator<Item=u8> + Clone, + M : Iterator<Item=u8>, +{ + let key_len = key.clone().count(); + let key = if key_len > 64 { + KeyOrHash::from_hash(T::hash(&key.collect::<Vec<_>>())) + } 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::<Vec<_>>()); + T::hash(&outer_pad.iter().chain(hash.as_ref().iter()).copied().collect::<Vec<_>>()) +} + +enum KeyOrHash<K: Iterator<Item=u8>, H: AsRef<[u8]>> { + Key(K), + Hash{ + hash : H, + idx : usize + } +} + +impl<K: Iterator<Item=u8>, H: AsRef<[u8]>> KeyOrHash<K, H>{ + fn from_key(key : K) -> Self { + Self::Key(key) + } + fn from_hash(hash : H) -> Self { + Self::Hash { hash, idx: 0 } + } +} + +impl<K: Iterator<Item=u8>, H: AsRef<[u8]>> Iterator for KeyOrHash<K, H>{ + type Item = u8; + fn next(&mut self) -> Option<Self::Item> { + 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 |