module Crypto.PHKDF.HMAC
( HmacCtx
, HmacKey
, hmacKey_init
, hmacKey_run
, hmacCtx_init
, hmacCtx_initFromHmacKey
, hmacCtx_update
, hmacCtx_updates
, hmacCtx_finalize
) where
import qualified Crypto.Hash.SHA256 as SHA256
import Data.Bits(xor)
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Crypto.PHKDF.HMAC.Subtle
hmacKey_init :: ByteString -> HmacKey
hmacKey_init :: ByteString -> HmacKey
hmacKey_init = HmacCtx -> HmacKey
HmacKey (HmacCtx -> HmacKey)
-> (ByteString -> HmacCtx) -> ByteString -> HmacKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> HmacCtx
hmacCtx_init
hmacCtx_init :: ByteString -> HmacCtx
hmacCtx_init :: ByteString -> HmacCtx
hmacCtx_init ByteString
key =
HmacCtx { hmacCtx_ipad :: Ctx
hmacCtx_ipad = Word8 -> Ctx
tweak Word8
0x36, hmacCtx_opad :: Ctx
hmacCtx_opad = Word8 -> Ctx
tweak Word8
0x5c }
where
tweak :: Word8 -> Ctx
tweak Word8
c = Ctx -> ByteString -> Ctx
SHA256.update Ctx
SHA256.init (ByteString -> Ctx) -> ByteString -> Ctx
forall a b. (a -> b) -> a -> b
$ (Word8 -> Word8) -> ByteString -> ByteString
B.map (Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
xor Word8
c) ByteString
k2
k1 :: ByteString
k1 = if ByteString -> Int
B.length ByteString
key Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
64 then ByteString -> ByteString
SHA256.hash ByteString
key else ByteString
key
k2 :: ByteString
k2 = ByteString -> ByteString -> ByteString
B.append ByteString
k1 (Int -> Word8 -> ByteString
B.replicate (Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
- ByteString -> Int
B.length ByteString
k1) Word8
0)
hmacCtx_initFromHmacKey :: HmacKey -> HmacCtx
hmacCtx_initFromHmacKey :: HmacKey -> HmacCtx
hmacCtx_initFromHmacKey = HmacKey -> HmacCtx
hmacKey_run
hmacCtx_update :: ByteString -> HmacCtx -> HmacCtx
hmacCtx_update :: ByteString -> HmacCtx -> HmacCtx
hmacCtx_update ByteString
b (HmacCtx Ctx
ic Ctx
oc) = Ctx -> Ctx -> HmacCtx
HmacCtx (Ctx -> ByteString -> Ctx
SHA256.update Ctx
ic ByteString
b) Ctx
oc
hmacCtx_updates :: [ByteString] -> HmacCtx -> HmacCtx
hmacCtx_updates :: [ByteString] -> HmacCtx -> HmacCtx
hmacCtx_updates [ByteString]
bs (HmacCtx Ctx
ic Ctx
oc) = Ctx -> Ctx -> HmacCtx
HmacCtx (Ctx -> [ByteString] -> Ctx
SHA256.updates Ctx
ic [ByteString]
bs) Ctx
oc
hmacCtx_finalize :: HmacCtx -> ByteString
hmacCtx_finalize :: HmacCtx -> ByteString
hmacCtx_finalize (HmacCtx Ctx
ic Ctx
oc) = ByteString
outer
where
inner :: ByteString
inner = Ctx -> ByteString
SHA256.finalize Ctx
ic
outer :: ByteString
outer = Ctx -> ByteString
SHA256.finalize (Ctx -> ByteString -> Ctx
SHA256.update Ctx
oc ByteString
inner)