Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use digestif 1.2.0 API #215

Merged
merged 3 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions ec/mirage_crypto_ec.ml
Original file line number Diff line number Diff line change
Expand Up @@ -967,15 +967,22 @@ module Ed25519 = struct

type priv = string

let sha512 datas =
let open Digestif.SHA512 in
let buf = Bytes.create digest_size in
let ctx = List.fold_left (feed_string ?off:None ?len:None) empty datas in
get_into_bytes ctx buf;
buf

(* RFC 8032 *)
let public secret =
(* section 5.1.5 *)
(* step 1 *)
let h = Digestif.SHA512.(digest_string secret |> to_raw_string) in
let h = sha512 [ secret ] in
(* step 2 *)
let s, rest =
Bytes.unsafe_of_string (String.sub h 0 key_len),
String.sub h key_len (String.length h - key_len)
Bytes.sub h 0 key_len,
Bytes.unsafe_to_string (Bytes.sub h key_len (Bytes.length h - key_len))
in
Bytes.set_uint8 s 0 ((Bytes.get_uint8 s 0) land 248);
Bytes.set_uint8 s 31 (((Bytes.get_uint8 s 31) land 127) lor 64);
Expand Down Expand Up @@ -1009,13 +1016,11 @@ module Ed25519 = struct
let sign ~key msg =
(* section 5.1.6 *)
let pub, (s, prefix) = public key in
let r = Digestif.SHA512.(digest_string (String.concat "" [ prefix; msg ]) |> to_raw_string) in
let r = Bytes.unsafe_of_string r in
let r = sha512 [ prefix; msg ] in
reduce_l r;
let r = Bytes.unsafe_to_string r in
let r_big = scalar_mult_base_to_bytes r in
let k = Digestif.SHA512.(digest_string (String.concat "" [ r_big; pub; msg]) |> to_raw_string) in
let k = Bytes.unsafe_of_string k in
let k = sha512 [ r_big; pub; msg] in
reduce_l k;
let k = Bytes.unsafe_to_string k in
let s_out = muladd k s r in
Expand All @@ -1041,10 +1046,7 @@ module Ed25519 = struct
String.equal s'' s'
in
if s_smaller_l then begin
let k =
Digestif.SHA512.(digest_string (String.concat "" [ r ; key ; msg ]) |> to_raw_string)
in
let k = Bytes.unsafe_of_string k in
let k = sha512 [ r ; key ; msg ] in
reduce_l k;
let k = Bytes.unsafe_to_string k in
let success, r' = double_scalar_mult k key s in
Expand Down
2 changes: 1 addition & 1 deletion mirage-crypto-ec.opam
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ depends: [
"dune-configurator"
"eqaf" {>= "0.7"}
"mirage-crypto-rng" {=version}
"digestif" {>= "1.1.4"}
"digestif" {>= "1.2.0"}
"hex" {with-test}
"alcotest" {with-test & >= "0.8.1"}
"ppx_deriving_yojson" {with-test}
Expand Down
2 changes: 1 addition & 1 deletion mirage-crypto-pk.opam
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ depends: [
"randomconv" {with-test & >= "0.2.0"}
"mirage-crypto" {=version}
"mirage-crypto-rng" {=version}
"digestif" {>= "1.1.4"}
"digestif" {>= "1.2.0"}
"zarith" {>= "1.13"}
"eqaf" {>= "0.8"}
]
Expand Down
13 changes: 5 additions & 8 deletions pk/mirage_crypto_pk.mli
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,12 @@ module Rsa : sig
was produced with the given [key] as per {{!sig_encode}sig_encode}, or
[None] *)

type hash = [ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ]
(** The type of supported hash algorithms. *)

val min_key : hash -> bits
val min_key : [< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] -> bits
(** [min_key hash] is the minimum key size required by {{!sign}[sign]}. *)

val sign : ?crt_hardening:bool -> ?mask:mask ->
hash:hash -> key:priv -> string or_digest ->
string
hash:[< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] ->
key:priv -> string or_digest -> string
(** [sign ~crt_hardening ~mask ~hash ~key message] is the PKCS 1.5
signature of [message], signed by the [key], using the hash function
[hash]. This is the full signature, with the ASN-encoded message digest
Expand All @@ -208,8 +205,8 @@ module Rsa : sig

@raise Invalid_argument if message is a [`Digest] of the wrong size. *)

val verify : hashp:(hash -> bool) -> key:pub ->
signature:string -> string or_digest -> bool
val verify : hashp:([< Digestif.hash' > `MD5 `SHA1 `SHA224 `SHA256 `SHA384 `SHA512 ] -> bool) ->
key:pub -> signature:string -> string or_digest -> bool
(** [verify ~hashp ~key ~signature message] checks that [signature] is the
PKCS 1.5 signature of the [message] under the given [key].

Expand Down
91 changes: 23 additions & 68 deletions pk/rsa.ml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,6 @@ module Digest_or (H : Digestif.S) = struct
invalid_arg "(`Digest _): %d bytes, expecting %d" n m
end

let digest_or (type a) ~(hash : a Digestif.hash) =
let module H = (val Digestif.module_of hash) in
let module D = Digest_or (H) in
D.digest_or

exception Insufficient_key

type pub = { e : Z.t ; n : Z.t }
Expand Down Expand Up @@ -274,69 +269,23 @@ module PKCS1 = struct
String.length msg >= String.length asn &&
String.equal asn (String.sub msg 0 (String.length asn))

type hash = [ `MD5 | `SHA1 | `SHA224 | `SHA256 | `SHA384 | `SHA512 ]

let digestif_or = function
| `MD5 -> digest_or ~hash:Digestif.md5
| `SHA1 -> digest_or ~hash:Digestif.sha1
| `SHA224 -> digest_or ~hash:Digestif.sha224
| `SHA256 -> digest_or ~hash:Digestif.sha256
| `SHA384 -> digest_or ~hash:Digestif.sha384
| `SHA512 -> digest_or ~hash:Digestif.sha512

let digestif_size = function
| `MD5 ->
let module H = (val Digestif.module_of Digestif.md5) in
H.digest_size
| `SHA1 ->
let module H = (val Digestif.module_of Digestif.sha1) in
H.digest_size
| `SHA224 ->
let module H = (val Digestif.module_of Digestif.sha224) in
H.digest_size
| `SHA256 ->
let module H = (val Digestif.module_of Digestif.sha256) in
H.digest_size
| `SHA384 ->
let module H = (val Digestif.module_of Digestif.sha384) in
H.digest_size
| `SHA512 ->
let module H = (val Digestif.module_of Digestif.sha512) in
H.digest_size

let asn_of_hash, detect =
let md5 = "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10"
and sha1 = "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14"
and sha224 = "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c"
and sha256 = "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20"
and sha384 = "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30"
and sha512 = "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"
let map = [
`MD5, "\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10" ;
`SHA1, "\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14" ;
`SHA224, "\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c" ;
`SHA256, "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20" ;
`SHA384, "\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30" ;
`SHA512, "\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40"
]
in
(function
| `MD5 -> md5
| `SHA1 -> sha1
| `SHA224 -> sha224
| `SHA256 -> sha256
| `SHA384 -> sha384
| `SHA512 -> sha512),
(fun buf ->
if is_prefix md5 buf then
Some (`MD5, md5)
else if is_prefix sha1 buf then
Some (`SHA1, sha1)
else if is_prefix sha224 buf then
Some (`SHA224, sha224)
else if is_prefix sha256 buf then
Some (`SHA256, sha256)
else if is_prefix sha384 buf then
Some (`SHA384, sha384)
else if is_prefix sha512 buf then
Some (`SHA512, sha512)
else
None)
(fun h -> List.assoc h map),
(fun buf -> List.find_opt (fun (_, d) -> is_prefix d buf) map)

let sign ?(crt_hardening = true) ?mask ~hash ~key msg =
let msg' = asn_of_hash hash ^ digestif_or hash msg in
let module H = (val Digestif.module_of_hash' (hash :> Digestif.hash')) in
let module D = Digest_or(H) in
let msg' = asn_of_hash hash ^ D.digest_or msg in
sig_encode ~crt_hardening ?mask ~key msg'

let verify ~hashp ~key ~signature msg =
Expand All @@ -346,11 +295,14 @@ module PKCS1 = struct
Option.value
(sig_decode ~key signature >>= fun buf ->
detect buf >>| fun (hash, asn) ->
hashp hash && Eqaf.equal (asn ^ digestif_or hash msg) buf)
let module H = (val Digestif.module_of_hash' (hash :> Digestif.hash')) in
let module D = Digest_or(H) in
hashp hash && Eqaf.equal (asn ^ D.digest_or msg) buf)
~default:false

let min_key hash =
(String.length (asn_of_hash hash) + digestif_size hash + min_pad + 2) * 8 + 1
let module H = (val Digestif.module_of_hash' (hash :> Digestif.hash')) in
(String.length (asn_of_hash hash) + H.digest_size + min_pad + 2) * 8 + 1
end

module MGF1 (H : Digestif.S) = struct
Expand All @@ -364,8 +316,11 @@ module MGF1 (H : Digestif.S) = struct
let mgf ~seed len =
let rec go acc c = function
| 0 -> Bytes.sub (Bytes.concat Bytes.empty (List.rev acc)) 0 len
| n -> let h = Bytes.unsafe_of_string H.(digesti_string (iter2 seed (repr c)) |> to_raw_string) in
go (h :: acc) Int32.(succ c) (pred n) in
| n ->
let h = Bytes.create H.digest_size in
H.get_into_bytes (H.feedi_string H.empty (iter2 seed (repr c))) h;
go (h :: acc) Int32.(succ c) (pred n)
in
go [] 0l (len // H.digest_size)

let mask ~seed buf =
Expand Down
Loading