commit b7fff78e638b0b09f5c2b02650047641bea91918
parent c454a32a4a39b0e18601b8139a12ae895c9b631e
Author: Jared Tobin <jared@jtobin.io>
Date: Sun, 6 Oct 2024 20:41:42 +0400
lib: hash long keys in hmac
Diffstat:
1 file changed, 23 insertions(+), 11 deletions(-)
diff --git a/lib/Crypto/Hash/SHA512.hs b/lib/Crypto/Hash/SHA512.hs
@@ -500,29 +500,41 @@ hash_lazy bl = cat (go iv (pad_lazy bl)) where
--
-- The 512-bit MAC is returned as a strict bytestring.
--
+-- Per RFC 2104, the key /should/ be a minimum of 64 bytes long. Keys
+-- exceeding 1024 bytes in length will first be hashed (via SHA-512).
+--
-- >>> hmac "strict bytestring key" "strict bytestring input"
-- "<strict 512-bit MAC>"
hmac :: BS.ByteString -> BS.ByteString -> BS.ByteString
hmac k = hmac_lazy k . BL.fromStrict
+data KeyAndLen = KeyAndLen
+ {-# UNPACK #-} !BS.ByteString
+ {-# UNPACK #-} !Int
+
-- | Produce a message authentication code for a lazy bytestring, based
-- on the provided (strict, bytestring) key, via SHA-512.
--
-- The 512-bit MAC is returned as a strict bytestring.
--
+-- Per RFC 2104, the key /should/ be a minimum of 64 bytes long. Keys
+-- exceeding 1024 bytes in length will first be hashed (via SHA-512).
+--
-- >>> hmac_lazy "strict bytestring key" "lazy bytestring input"
-- "<strict 512-bit MAC>"
hmac_lazy :: BS.ByteString -> BL.ByteString -> BS.ByteString
-hmac_lazy k text
- | lk > 128 = error "ppad-sha512: hmac key exceeds 128 bytes"
- | otherwise =
- let step1 = k <> BS.replicate (128 - lk) 0x00
- step2 = BS.map (B.xor 0x36) step1
- step3 = BL.fromStrict step2 <> text
- step4 = hash_lazy step3
- step5 = BS.map (B.xor 0x5C) step1
- step6 = step5 <> step4
- in hash step6
+hmac_lazy mk text =
+ let step1 = k <> BS.replicate (128 - lk) 0x00
+ step2 = BS.map (B.xor 0x36) step1
+ step3 = BL.fromStrict step2 <> text
+ step4 = hash_lazy step3
+ step5 = BS.map (B.xor 0x5C) step1
+ step6 = step5 <> step4
+ in hash step6
where
- lk = fi (BS.length k)
+ !(KeyAndLen k lk) =
+ let l = BS.length mk
+ in if l > 128
+ then KeyAndLen (hash mk) 64
+ else KeyAndLen mk l