Verified Commit 928ee9d3 authored by Vincent Bernardoff's avatar Vincent Bernardoff Committed by Grégoire Henry

Hacl: add HMAC_SHA512

parent a3cfcc09
......@@ -117,41 +117,77 @@ module Hash = struct
Bigstring.t -> Bigstring.t -> Bigstring.t -> unit =
"ml_Hacl_HMAC_SHA2_256_hmac" [@@noalloc]
let write_hmac ~key ~msg buf =
if Bigstring.length buf < 32 then
invalid_arg (Printf.sprintf "Hash.write_hmac_sha156: invalid len \
%d" 32) ;
let write ~key ~msg buf =
let buflen = Bigstring.length buf in
if buflen < 32 then
invalid_arg (Printf.sprintf "Hash.SHA256.HMAC.write: invalid \
len (%d), expected %d" buflen bytes) ;
hmac buf key msg
let hmac ~key ~msg =
let digest ~key ~msg =
let buf = Bigstring.create 32 in
write_hmac ~key ~msg buf ;
write ~key ~msg buf ;
buf
end
end
module SHA512 = Make(struct
(* state -> unit *)
external init : Bigstring.t -> unit =
"ml_Hacl_SHA2_512_init" [@@noalloc]
module SHA512 = struct
module H = Make(struct
(* state -> unit *)
external init : Bigstring.t -> unit =
"ml_Hacl_SHA2_512_init" [@@noalloc]
(* state -> data -> unit *)
external update : Bigstring.t -> Bigstring.t -> unit =
"ml_Hacl_SHA2_512_update" [@@noalloc]
(* state -> data -> unit *)
external update : Bigstring.t -> Bigstring.t -> unit =
"ml_Hacl_SHA2_512_update" [@@noalloc]
(* state -> data -> datalen -> unit *)
external update_last : Bigstring.t -> Bigstring.t -> int -> unit =
"ml_Hacl_SHA2_512_update_last" [@@noalloc]
(* state -> data -> datalen -> unit *)
external update_last : Bigstring.t -> Bigstring.t -> int -> unit =
"ml_Hacl_SHA2_512_update_last" [@@noalloc]
(* state -> hash *)
external finish : Bigstring.t -> Bigstring.t -> unit =
"ml_Hacl_SHA2_512_finish" [@@noalloc]
(* state -> hash *)
external finish : Bigstring.t -> Bigstring.t -> unit =
"ml_Hacl_SHA2_512_finish" [@@noalloc]
let bytes = 64
let blockbytes = 128
let statebytes = 169 * 8
end)
include H
let bytes = 64
let blockbytes = 128
let statebytes = 169 * 8
end)
module HMAC = struct
let derive_key k =
let buf = Bigstring.create blockbytes in
Bigstring.fill buf '\x00' ;
let keylen = Bigstring.length k in
let k, keylen =
if keylen > blockbytes then H.digest k, bytes else k, keylen in
Bigstring.blit k 0 buf 0 keylen ;
buf
let xor_ipad =
Bigstring.map ~f:(fun c -> Char.(chr ((code c) lxor 0x36)))
let xor_opad =
Bigstring.map ~f:(fun c -> Char.(chr ((code c) lxor 0x5c)))
let digest ~key ~msg =
let key = derive_key key in
let preimage =
Bigstring.concat "" [
xor_opad key ;
digest (Bigstring.concat "" [xor_ipad key ; msg])
] in
digest preimage
let write ~key ~msg buf =
let buflen = Bigstring.length buf in
if buflen < bytes then
invalid_arg (Printf.sprintf "Hash.SHA512.HMAC.write: invalid \
len (%d), expected %d" buflen bytes) ;
let d = digest ~key ~msg in
Bigstring.blit d 0 buf 0 bytes
end
end
end
module Nonce = struct
......
......@@ -46,11 +46,11 @@ module Hash : sig
val digest : Bigstring.t -> Bigstring.t
module HMAC : sig
val write_hmac :
val write :
key:Bigstring.t -> msg:Bigstring.t -> Bigstring.t -> unit
(** @raise [Invalid_argument] if argument is less than 32 bytes long *)
val hmac :
val digest :
key:Bigstring.t -> msg:Bigstring.t -> Bigstring.t
end
end
......@@ -71,6 +71,15 @@ module Hash : sig
(** Direct Interface *)
val digest : Bigstring.t -> Bigstring.t
module HMAC : sig
val write :
key:Bigstring.t -> msg:Bigstring.t -> Bigstring.t -> unit
(** @raise [Invalid_argument] if argument is less than 32 bytes long *)
val digest :
key:Bigstring.t -> msg:Bigstring.t -> Bigstring.t
end
end
end
......
......@@ -84,11 +84,26 @@ let hmac_sha256 () =
let key = Bigstring.of_string "key" in
let msg = Bigstring.of_string "The quick brown fox jumps over the lazy dog" in
let resp = of_hex "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8" in
let digest = Hash.HMAC_SHA256.hmac ~key ~msg in
let digest = Hash.SHA256.HMAC.digest ~key ~msg in
Alcotest.(check bigstring "hmac_sha256" resp digest)
let hmac_sha512 () =
let vectors = [
Bigstring.of_string "key",
Bigstring.of_string "The quick brown fox jumps over the lazy dog",
of_hex "b42af09057bac1e2d41708e48a902e09b5ff7f12ab428a4fe86653c73dd248fb82f948a549f7b791a5b41915ee4d1ec3935357e4e2317250d0372afa2ebeeb3a" ;
Bigstring.empty,
Bigstring.empty,
of_hex "b936cee86c9f87aa5d3c6f2e84cb5a4239a5fe50480a6ec66b70ab5b1f4ac6730c6c515421b327ec1d69402e53dfb49ad7381eb067b338fd7b0cb22247225d47" ;
] in
List.iter begin fun (key, msg, resp) ->
let digest = Hash.SHA512.HMAC.digest ~key ~msg in
Alcotest.(check bigstring "hmac_sha512" resp digest)
end vectors
let hash = [
"hmac_sha256", `Quick, hmac_sha256 ;
"hmac_sha512", `Quick, hmac_sha512 ;
"sha256", `Quick, sha256 ;
"sha256_seq", `Quick, sha256_seq ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment