sasl-0.0.0.0: src/Network/Sasl/ScramSha1/Hmac.hs
module Network.Sasl.ScramSha1.Hmac (hmac, bsToHex) where
import Data.Word
import Data.Bits
import Numeric
import qualified Data.ByteString as BS
type Hash = BS.ByteString -> BS.ByteString
ipad, opad :: [Word8]
ipad = repeat 0x36
opad = repeat 0x5c
hmac :: Hash -> Int -> BS.ByteString -> BS.ByteString -> BS.ByteString
hmac h bs k = h . (makePad opad k' `BS.append`) . h . (makePad ipad k' `BS.append`)
where
k' = makeKey h bs k
makeKey :: Hash -> Int -> BS.ByteString -> BS.ByteString
makeKey h bs k
| BS.length k > bs = makeKey h bs $ h k
| otherwise = k `BS.append` BS.replicate (bs - BS.length k) 0
makePad :: [Word8] -> BS.ByteString -> BS.ByteString
makePad iop = BS.pack . mkp iop . BS.unpack
where
mkp _ [] = []
mkp (p : ps) (k : ks) = p `xor` k : mkp ps ks
mkp _ _ = error "makePad: bad"
bsToHex :: BS.ByteString -> String
bsToHex = concatMap (`showHex` "") . BS.unpack