packages feed

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