0 | module Crypto.Hash.HMAC
 1 |
 2 | import Crypto.Hash
 3 | import Data.Bits
 4 | import Data.List
 5 | import Data.Vect
 6 |
 7 | export
 8 | data HMAC : Type -> Type where
 9 |   MkHMAC : (o_key_pad : List Bits8) -> algo -> HMAC algo
10 |
11 | process_key : (0 algo : Type) -> Hash algo => List Bits8 -> List Bits8
12 | process_key algo key =
13 |   if length key > block_nbyte {algo}
14 |     then toList $ hash algo key
15 |     else key <+> (List.replicate (minus (block_nbyte {algo}) $ length key) 0)
16 |
17 | export
18 | Hash algo => Digest (HMAC algo) where
19 |   digest_nbyte = digest_nbyte {algo}
20 |   finalize (MkHMAC o_key_pad underlying) = hash algo $ o_key_pad <+> toList (finalize underlying)
21 |   update message (MkHMAC o_key_pad underlying) = MkHMAC o_key_pad $ update message underlying
22 |
23 | export
24 | Hash algo => MAC (List Bits8) (HMAC algo) where
25 |   initialize_mac key =
26 |     let key = HMAC.process_key algo key
27 |         o_key_pad = zipWith xor key $ replicate (block_nbyte {algo}) 0x5c
28 |         i_key_pad = zipWith xor key $ replicate (block_nbyte {algo}) 0x36
29 |     in MkHMAC o_key_pad (update i_key_pad initialize)
30 |