Hacl: add HMAC_SHA512

This commit is contained in:
Vincent Bernardoff 2018-07-02 10:43:28 +02:00 committed by Grégoire Henry
parent a3cfcc091a
commit 928ee9d3a0
No known key found for this signature in database
GPG Key ID: 50D984F20BD445D2
3 changed files with 86 additions and 26 deletions

View File

@ -117,41 +117,77 @@ module Hash = struct
Bigstring.t -> Bigstring.t -> Bigstring.t -> unit = Bigstring.t -> Bigstring.t -> Bigstring.t -> unit =
"ml_Hacl_HMAC_SHA2_256_hmac" [@@noalloc] "ml_Hacl_HMAC_SHA2_256_hmac" [@@noalloc]
let write_hmac ~key ~msg buf = let write ~key ~msg buf =
if Bigstring.length buf < 32 then let buflen = Bigstring.length buf in
invalid_arg (Printf.sprintf "Hash.write_hmac_sha156: invalid len \ if buflen < 32 then
%d" 32) ; invalid_arg (Printf.sprintf "Hash.SHA256.HMAC.write: invalid \
len (%d), expected %d" buflen bytes) ;
hmac buf key msg hmac buf key msg
let hmac ~key ~msg = let digest ~key ~msg =
let buf = Bigstring.create 32 in let buf = Bigstring.create 32 in
write_hmac ~key ~msg buf ; write ~key ~msg buf ;
buf buf
end end
end end
module SHA512 = Make(struct module SHA512 = struct
(* state -> unit *) module H = Make(struct
external init : Bigstring.t -> unit = (* state -> unit *)
"ml_Hacl_SHA2_512_init" [@@noalloc] external init : Bigstring.t -> unit =
"ml_Hacl_SHA2_512_init" [@@noalloc]
(* state -> data -> unit *) (* state -> data -> unit *)
external update : Bigstring.t -> Bigstring.t -> unit = external update : Bigstring.t -> Bigstring.t -> unit =
"ml_Hacl_SHA2_512_update" [@@noalloc] "ml_Hacl_SHA2_512_update" [@@noalloc]
(* state -> data -> datalen -> unit *) (* state -> data -> datalen -> unit *)
external update_last : Bigstring.t -> Bigstring.t -> int -> unit = external update_last : Bigstring.t -> Bigstring.t -> int -> unit =
"ml_Hacl_SHA2_512_update_last" [@@noalloc] "ml_Hacl_SHA2_512_update_last" [@@noalloc]
(* state -> hash *) (* state -> hash *)
external finish : Bigstring.t -> Bigstring.t -> unit = external finish : Bigstring.t -> Bigstring.t -> unit =
"ml_Hacl_SHA2_512_finish" [@@noalloc] "ml_Hacl_SHA2_512_finish" [@@noalloc]
let bytes = 64 let bytes = 64
let blockbytes = 128 let blockbytes = 128
let statebytes = 169 * 8 let statebytes = 169 * 8
end) end)
include H
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 end
module Nonce = struct module Nonce = struct

View File

@ -46,11 +46,11 @@ module Hash : sig
val digest : Bigstring.t -> Bigstring.t val digest : Bigstring.t -> Bigstring.t
module HMAC : sig module HMAC : sig
val write_hmac : val write :
key:Bigstring.t -> msg:Bigstring.t -> Bigstring.t -> unit key:Bigstring.t -> msg:Bigstring.t -> Bigstring.t -> unit
(** @raise [Invalid_argument] if argument is less than 32 bytes long *) (** @raise [Invalid_argument] if argument is less than 32 bytes long *)
val hmac : val digest :
key:Bigstring.t -> msg:Bigstring.t -> Bigstring.t key:Bigstring.t -> msg:Bigstring.t -> Bigstring.t
end end
end end
@ -71,6 +71,15 @@ module Hash : sig
(** Direct Interface *) (** Direct Interface *)
val digest : Bigstring.t -> Bigstring.t 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
end end

View File

@ -84,11 +84,26 @@ let hmac_sha256 () =
let key = Bigstring.of_string "key" in let key = Bigstring.of_string "key" in
let msg = Bigstring.of_string "The quick brown fox jumps over the lazy dog" in let msg = Bigstring.of_string "The quick brown fox jumps over the lazy dog" in
let resp = of_hex "f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8" 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) 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 = [ let hash = [
"hmac_sha256", `Quick, hmac_sha256 ; "hmac_sha256", `Quick, hmac_sha256 ;
"hmac_sha512", `Quick, hmac_sha512 ;
"sha256", `Quick, sha256 ; "sha256", `Quick, sha256 ;
"sha256_seq", `Quick, sha256_seq ; "sha256_seq", `Quick, sha256_seq ;