···1414 val feed : t -> Cstruct.t -> t
1515 val get : t -> Cstruct.t
16161717+ type hmac
1818+1919+ val hmac_empty : key:Cstruct.t -> hmac
2020+ val hmac_feed : hmac -> Cstruct.t -> hmac
2121+ val hmac_get : hmac -> digest
2222+1723 val digest : Cstruct.t -> digest
1824 val hmac : key:Cstruct.t -> Cstruct.t -> digest
1925···72787379 include Core (F) (D)
74808181+ type hmac = t * t
8282+7583 let opad =
7684 let buf = Cstruct.create block_size in
7785 Cstruct.memset buf 0x5c;
···8694 | 1 -> norm (digest key)
8795 | -1 -> Cs.rpad key block_size 0
8896 | _ -> key
9797+9898+ let hmac_empty ~key =
9999+ let key = norm key in
100100+ let outer = Cs.xor key opad
101101+ and inner = Cs.xor key ipad in
102102+ feed empty inner, feed empty outer
103103+104104+ let hmac_feed (t, outer) cs =
105105+ feed t cs, outer
106106+107107+ let hmac_get (t, outer) =
108108+ get (feed outer (get t))
8910990110 let hmaci ~key iter =
91111 let key = norm key in
+15
src/mirage_crypto.mli
···114114 val get : t -> digest
115115 (** [get t] is the digest corresponding to [t]. *)
116116117117+ (** {1 HMAC operations} *)
118118+119119+ type hmac
120120+ (** Represents a running hmac computation in a way suitable for appending
121121+ inputs. *)
122122+123123+ val hmac_empty : key:Cstruct.t -> hmac
124124+ (** [hmac ~key] is the hmac of the empty string using key [key]. *)
125125+126126+ val hmac_feed : hmac -> Cstruct.t -> hmac
127127+ (** [feed hmac msg] is analogous to [feed]. *)
128128+129129+ val hmac_get : hmac -> digest
130130+ (** [hmac_get hmac] is the hmac corresponding to [hmac]. *)
131131+117132 (** {1 All-in-one}
118133119134 Functions that operate on data stored in a single chunk. *)
+19-1
tests/test_hmac.ml
···221221let test_hmac name id =
222222 List.mapi (fun i args -> "HMAC " ^ name ^ " " ^ string_of_int i >:: test id i args)
223223224224+let test_feed hash i ((key, data), result) _ =
225225+ let (module H) = Hash.module_of hash in
226226+ let empty = H.hmac_empty ~key in
227227+ let computed = H.hmac_get (H.hmac_feed empty data) in
228228+ if i == 4 (* truncated thingy *) then
229229+ assert_cs_equal result Cstruct.(sub computed 0 (len result))
230230+ else
231231+ assert_cs_equal result computed
232232+233233+let test_feed_hmac name id =
234234+ List.mapi (fun i args -> "HMAC feed " ^ name ^ " " ^ string_of_int i >:: test_feed id i args)
235235+224236let suite =
225237 test_hmac "MD5" `MD5 (List.combine md5_inputs md5_results) @
226238 test_hmac "SHA1" `SHA1 (List.combine sha1_inputs sha1_results) @
227239 test_hmac "SHA224" `SHA224 (List.combine sha2_inputs sha224_results) @
228240 test_hmac "SHA256" `SHA256 (List.combine sha2_inputs sha256_results) @
229241 test_hmac "SHA384" `SHA384 (List.combine sha2_inputs sha384_results) @
230230- test_hmac "SHA512" `SHA512 (List.combine sha2_inputs sha512_results)
242242+ test_hmac "SHA512" `SHA512 (List.combine sha2_inputs sha512_results) @
243243+ test_feed_hmac "MD5" `MD5 (List.combine md5_inputs md5_results) @
244244+ test_feed_hmac "SHA1" `SHA1 (List.combine sha1_inputs sha1_results) @
245245+ test_feed_hmac "SHA224" `SHA224 (List.combine sha2_inputs sha224_results) @
246246+ test_feed_hmac "SHA256" `SHA256 (List.combine sha2_inputs sha256_results) @
247247+ test_feed_hmac "SHA384" `SHA384 (List.combine sha2_inputs sha384_results) @
248248+ test_feed_hmac "SHA512" `SHA512 (List.combine sha2_inputs sha512_results)