From 8b6f90c3cc4640864dc8b5ef30ffcb1e45c1c9eb Mon Sep 17 00:00:00 2001 From: Hannes Mehnert Date: Wed, 28 Feb 2024 13:40:20 +0100 Subject: [PATCH] mirage-crypto-pk: remove s-expression converters and sexplib0 dependency --- mirage-crypto-pk.opam | 1 - pk/common.ml | 4 ---- pk/dh.ml | 50 ---------------------------------------- pk/dsa.ml | 31 ------------------------- pk/dune | 2 +- pk/mirage_crypto_pk.mli | 51 +++++------------------------------------ pk/rsa.ml | 33 -------------------------- tests/test_rsa.ml | 39 +++++++++++++++---------------- 8 files changed, 26 insertions(+), 185 deletions(-) diff --git a/mirage-crypto-pk.opam b/mirage-crypto-pk.opam index ace4c055..9a4dfa75 100644 --- a/mirage-crypto-pk.opam +++ b/mirage-crypto-pk.opam @@ -21,7 +21,6 @@ depends: [ "cstruct" {>="6.00"} "mirage-crypto" {=version} "mirage-crypto-rng" {=version} - "sexplib0" "zarith" {>= "1.4"} "eqaf" {>= "0.8"} ] diff --git a/pk/common.ml b/pk/common.ml index 59445afb..01ad98b2 100644 --- a/pk/common.ml +++ b/pk/common.ml @@ -3,7 +3,3 @@ let rec until p f = let r = f () in if p r then r else until p f let guard p err = if p then Ok () else Error err let ( let* ) = Result.bind - -open Sexplib0.Sexp_conv -let sexp_of_z z = sexp_of_string (Z.to_string z) -let z_of_sexp s = Z.of_string (string_of_sexp s) diff --git a/pk/dh.ml b/pk/dh.ml index 665f25ee..d0fc3890 100644 --- a/pk/dh.ml +++ b/pk/dh.ml @@ -1,5 +1,4 @@ open Mirage_crypto.Uncommon -open Sexplib0.Sexp_conv open Common @@ -11,25 +10,6 @@ type group = { q : Z.t option ; (* `gg`'s order, maybe *) } -let sexp_of_group g = - Sexplib0.Sexp.List - [ - sexp_of_pair sexp_of_string sexp_of_z ("p", g.p) ; - sexp_of_pair sexp_of_string sexp_of_z ("gg", g.gg) ; - sexp_of_pair sexp_of_string (sexp_of_option sexp_of_z) ("q", g.q) - ] - -let group_of_sexp = function - | Sexplib0.Sexp.List [ p ; gg ; q ] as s -> - let p_str, p = pair_of_sexp string_of_sexp z_of_sexp p in - let gg_str, gg = pair_of_sexp string_of_sexp z_of_sexp gg in - let q_str, q = pair_of_sexp string_of_sexp (option_of_sexp z_of_sexp) q in - if p_str = "p" && gg_str = "gg" && q_str = "q" then - { p ; gg ; q } - else - raise (Of_sexp_error (Failure "expected p, gg, and q", s)) - | s -> raise (Of_sexp_error (Failure "expected a list with 3 elements", s)) - let group ~p ~gg ?q () = let* () = guard (Z.(p > zero && is_odd p) && Z_extra.pseudoprime p) @@ -40,38 +20,8 @@ let group ~p ~gg ?q () = in Ok { p ; gg ; q } -let group_of_sexp s = - let g = group_of_sexp s in - match group ~p:g.p ~gg:g.gg ?q:g.q () with - | Error (`Msg m) -> invalid_arg "bad group: %s" m - | Ok g -> g - type secret = { group : group ; x : Z.t } -let sexp_of_secret s = - Sexplib0.Sexp.List - [ - sexp_of_pair sexp_of_string sexp_of_group ("group", s.group) ; - sexp_of_pair sexp_of_string sexp_of_z ("x", s.x) ; - ] - -let secret_of_sexp = function - | Sexplib0.Sexp.List [ group ; x ] as s -> - let group_str, group = pair_of_sexp string_of_sexp group_of_sexp group in - let x_str, x = pair_of_sexp string_of_sexp z_of_sexp x in - if group_str = "group" && x_str = "x" then - { group ; x } - else - raise (Of_sexp_error (Failure "expected group and x", s)) - | s -> raise (Of_sexp_error (Failure "expected a list with 2 elements", s)) - -let secret_of_sexp sexp = - let s = secret_of_sexp sexp in - if Z.(one < s.x && s.x < s.group.p) then - s - else - invalid_arg "bad secret" - (* * Estimates of equivalent-strength exponent sizes for the moduli sizes. * 2048-8192 are taken from "Negotiated FF DHE Parameters for TLS." diff --git a/pk/dsa.ml b/pk/dsa.ml index f096dd66..1690bfcd 100644 --- a/pk/dsa.ml +++ b/pk/dsa.ml @@ -1,19 +1,9 @@ open Mirage_crypto.Uncommon -open Sexplib0.Sexp_conv open Common type pub = { p : Z.t ; q : Z.t ; gg : Z.t ; y : Z.t } -let sexp_of_pub { p ; q ; gg ; y } = - sexp_of_list (sexp_of_pair sexp_of_string sexp_of_z) - [ "p", p; "q", q; "gg", gg; "y", y ] - -let pub_of_sexp s = - match list_of_sexp (pair_of_sexp string_of_sexp z_of_sexp) s with - | [ "p", p; "q", q; "gg", gg; "y", y ] -> { p ; q ; gg ; y } - | _ -> raise (Of_sexp_error (Failure "expected p, q, gg, and y'", s)) - let pub ?(fips = false) ~p ~q ~gg ~y () = let* () = guard Z.(one < gg && gg < p) (`Msg "bad generator") in let* () = guard (Z_extra.pseudoprime q) (`Msg "q is not prime") in @@ -31,36 +21,15 @@ let pub ?(fips = false) ~p ~q ~gg ~y () = in Ok { p ; q ; gg ; y } -let pub_of_sexp s = - let p = pub_of_sexp s in - match pub ?fips:None ~p:p.p ~q:p.q ~gg:p.gg ~y:p.y () with - | Ok p -> p - | Error (`Msg m) -> invalid_arg "bad public %s" m - type priv = { p : Z.t ; q : Z.t ; gg : Z.t ; x : Z.t ; y : Z.t } -let sexp_of_priv { p ; q ; gg ; x ; y } = - sexp_of_list (sexp_of_pair sexp_of_string sexp_of_z) - [ "p", p; "q", q; "gg", gg; "x", x; "y", y ] - -let priv_of_sexp s = - match list_of_sexp (pair_of_sexp string_of_sexp z_of_sexp) s with - | [ "p", p; "q", q; "gg", gg; "x", x; "y", y ] -> { p ; q ; gg ; x ; y } - | _ -> raise (Of_sexp_error (Failure "expected p, q, gg, x, and y'", s)) - let priv ?fips ~p ~q ~gg ~x ~y () = let* _ = pub ?fips ~p ~q ~gg ~y () in let* () = guard Z.(zero < x && x < q) (`Msg "x not in 1..q-1") in let* () = guard Z.(y = powm gg x p) (`Msg "y <> g ^ x mod p") in Ok { p ; q ; gg ; x ; y } -let priv_of_sexp s = - let p = priv_of_sexp s in - match priv ?fips:None ~p:p.p ~q:p.q ~gg:p.gg ~x:p.x ~y:p.y () with - | Ok p -> p - | Error (`Msg m) -> invalid_arg "bad private %s" m - let pub_of_priv { p; q; gg; y; _ } = { p; q; gg; y } type keysize = [ `Fips1024 | `Fips2048 | `Fips3072 | `Exactly of int * int ] diff --git a/pk/dune b/pk/dune index a93e6c52..aa7d8ba0 100644 --- a/pk/dune +++ b/pk/dune @@ -1,5 +1,5 @@ (library (name mirage_crypto_pk) (public_name mirage-crypto-pk) - (libraries cstruct zarith mirage-crypto mirage-crypto-rng sexplib0 eqaf.cstruct) + (libraries cstruct zarith mirage-crypto mirage-crypto-rng eqaf.cstruct) (private_modules common dh dsa rsa z_extra)) diff --git a/pk/mirage_crypto_pk.mli b/pk/mirage_crypto_pk.mli index ba3f4188..6c9ab505 100644 --- a/pk/mirage_crypto_pk.mli +++ b/pk/mirage_crypto_pk.mli @@ -30,9 +30,7 @@ module Rsa : sig e : Z.t ; (** Public exponent *) n : Z.t ; (** Modulus *) } - (** The public portion of the key. - - {e [Sexplib] convertible}. *) + (** The public portion of the key. *) val pub : e:Z.t -> n:Z.t -> (pub, [> `Msg of string ]) result (** [pub ~e ~n] validates the public key: [1 < e < n], [n > 0], @@ -55,9 +53,7 @@ module Rsa : sig Some systems assume otherwise. When using keys produced by a system that computes [u = p^(-1) mod q], either exchange [p] with [q] and [dp] with [dq], or re-generate the full private key using - {{!priv_of_primes}[priv_of_primes]}. - - {e [Sexplib] convertible}. *) + {{!priv_of_primes}[priv_of_primes]}. *) val priv : e:Z.t -> d:Z.t -> n:Z.t -> p:Z.t -> q:Z.t -> dp:Z.t -> dq:Z.t -> q':Z.t -> (priv, [> `Msg of string ]) result @@ -282,15 +278,6 @@ module Rsa : sig @raise Invalid_argument if message is a [`Digest] of the wrong size. *) end - - (**/**) - val pub_of_sexp : Sexplib0.Sexp.t -> pub - val sexp_of_pub : pub -> Sexplib0.Sexp.t - - val priv_of_sexp : Sexplib0.Sexp.t -> priv - val sexp_of_priv : priv -> Sexplib0.Sexp.t - (**/**) - end @@ -306,9 +293,7 @@ module Dsa : sig x : Z.t ; (** Private key proper *) y : Z.t ; (** Public component *) } - (** Private key. [p], [q] and [gg] comprise {i domain parameters}. - - {e [Sexplib] convertible}. *) + (** Private key. [p], [q] and [gg] comprise {i domain parameters}. *) val priv : ?fips:bool -> p:Z.t -> q:Z.t -> gg:Z.t -> x:Z.t -> y:Z.t -> unit -> (priv, [> `Msg of string ]) result @@ -323,9 +308,7 @@ module Dsa : sig gg : Z.t ; y : Z.t ; } - (** Public key, a subset of {{!type-priv}private key}. - - {e [Sexplib] convertible}. *) + (** Public key, a subset of {{!type-priv}private key}. *) val pub : ?fips:bool -> p:Z.t -> q:Z.t -> gg:Z.t -> y:Z.t -> unit -> (pub, [> `Msg of string ]) result @@ -396,15 +379,6 @@ module Dsa : sig (** [generate key digest] deterministically takes the given private key and message digest to a [k] suitable for seeding the signing process. *) end - - (**/**) - val pub_of_sexp : Sexplib0.Sexp.t -> pub - val sexp_of_pub : pub -> Sexplib0.Sexp.t - - val priv_of_sexp : Sexplib0.Sexp.t -> priv - val sexp_of_priv : priv -> Sexplib0.Sexp.t - (**/**) - end @@ -425,9 +399,7 @@ module Dh : sig gg : Z.t ; (** generator *) q : Z.t option ; (** subgroup order; potentially unknown *) } - (** A DH group. - - {e [Sexplib] convertible}. *) + (** A DH group. *) val group : p:Z.t -> gg:Z.t -> ?q:Z.t -> unit -> (group, [> `Msg of string ]) result @@ -435,9 +407,7 @@ module Dh : sig and greater than [zero]. [gg] must be in the range [1 < gg < p]. *) type secret = private { group : group ; x : Z.t } - (** A private key. - - {e [Sexplib] convertible.} *) + (** A private key. *) val modulus_size : group -> bits (** Bit size of the modulus. *) @@ -505,15 +475,6 @@ module Dh : sig val ffdhe8192 : group end - - (**/**) - val group_of_sexp : Sexplib0.Sexp.t -> group - val sexp_of_group : group -> Sexplib0.Sexp.t - - val secret_of_sexp : Sexplib0.Sexp.t -> secret - val sexp_of_secret : secret -> Sexplib0.Sexp.t - (**/**) - end (** {b Z} Convert Z to big endian Cstruct.t and generate random Z values. *) diff --git a/pk/rsa.ml b/pk/rsa.ml index 5220d105..0801ccf9 100644 --- a/pk/rsa.ml +++ b/pk/rsa.ml @@ -1,5 +1,4 @@ open Mirage_crypto.Uncommon -open Sexplib0.Sexp_conv open Common @@ -35,15 +34,6 @@ exception Insufficient_key type pub = { e : Z.t ; n : Z.t } -let sexp_of_pub { e ; n } = - sexp_of_list (sexp_of_pair sexp_of_string sexp_of_z) - [ "e", e ; "n" , n ] - -let pub_of_sexp s = - match list_of_sexp (pair_of_sexp string_of_sexp z_of_sexp) s with - | [ "e", e ; "n", n ] -> { e ; n } - | _ -> raise (Of_sexp_error (Failure "expected e and n", s)) - (* due to PKCS1 *) let minimum_octets = 12 let minimum_bits = 8 * minimum_octets - 7 @@ -65,28 +55,11 @@ let pub ~e ~n = these are not requirements, neither for RSA nor for powm_sec *) Ok { e ; n } -let pub_of_sexp s = - let p = pub_of_sexp s in - match pub ~e:p.e ~n:p.n with - | Ok p -> p - | Error (`Msg m) -> failwith "bad public key: %s" m - type priv = { e : Z.t ; d : Z.t ; n : Z.t ; p : Z.t ; q : Z.t ; dp : Z.t ; dq : Z.t ; q' : Z.t } -let sexp_of_priv { e ; d ; n ; p ; q ; dp ; dq ; q' } = - sexp_of_list (sexp_of_pair sexp_of_string sexp_of_z) - [ "e", e; "d", d; "n", n; "p", p; "q", q; "dp", dp; "dq", dq; "q'", q' ] - -let priv_of_sexp s = - match list_of_sexp (pair_of_sexp string_of_sexp z_of_sexp) s with - | [ "e", e; "d", d; "n", n; "p", p; "q", q; "dp", dp; "dq", dq; "q'", q' ] -> - { e ; d ; n ; p ; q ; dp ; dq ; q' } - | _ -> - raise (Of_sexp_error (Failure "expected e, d, n, p, q, dp, dq, and q'", s)) - let valid_prime name p = guard Z.(p > zero && is_odd p && Z_extra.pseudoprime p) (`Msg ("invalid prime " ^ name)) @@ -120,12 +93,6 @@ let priv ~e ~d ~n ~p ~q ~dp ~dq ~q' = in Ok { e ; d ; n ; p ; q ; dp ; dq ; q' } -let priv_of_sexp s = - let p = priv_of_sexp s in - match priv ~e:p.e ~d:p.d ~n:p.n ~p:p.p ~q:p.q ~dp:p.dp ~dq:p.dq ~q':p.q' with - | Error (`Msg m) -> failwith "invalid private key %s" m - | Ok p -> p - let priv_of_primes ~e ~p ~q = let* () = valid_prime "p" p in let* () = valid_prime "q" q in diff --git a/tests/test_rsa.ml b/tests/test_rsa.ml index c169486e..a580f18a 100644 --- a/tests/test_rsa.ml +++ b/tests/test_rsa.ml @@ -37,11 +37,10 @@ let random_is seed = let gen_rsa ~bits = let e = Z.(if bits < 24 then ~$3 else ~$0x10001) in let key = Rsa.(generate ~e ~bits ()) in - let key_s = Sexplib0.Sexp.to_string_hum Rsa.(sexp_of_priv key) in assert_equal - ~msg:Printf.(sprintf "key size not %d bits:\n%s" bits key_s) + ~msg:Printf.(sprintf "key size not %d bits" bits) bits Rsa.(priv_bits key); - (key, key_s) + key let rsa_priv_of_primes_regression _ = let e = Z.of_string "65537" @@ -89,12 +88,12 @@ let rsa_selftest ~bits n = Cstruct.set_uint8 cs 0 0; Cstruct.(set_uint8 cs i (get_uint8 cs i lor 2)); cs in - let (key, key_s) = gen_rsa ~bits in + let key = gen_rsa ~bits in let enc = Rsa.(encrypt ~key:(pub_of_priv key) msg) in let dec = Rsa.(decrypt ~key enc) in assert_cs_equal - ~msg:Printf.(sprintf "failed decryption with:\n%s" key_s) + ~msg:Printf.(sprintf "failed decryption with") msg dec let show_key_size key = @@ -107,9 +106,9 @@ let pkcs_message_for_bits bits = let rsa_pkcs1_encode_selftest ~bits n = "selftest" >:: times ~n @@ fun _ -> - let (key, _) = gen_rsa ~bits - and msg = pkcs_message_for_bits bits in - let sgn = Rsa.PKCS1.sig_encode ~key msg in + let key = gen_rsa ~bits + and msg = pkcs_message_for_bits bits in + let sgn = Rsa.PKCS1.sig_encode ~key msg in match Rsa.(PKCS1.sig_decode ~key:(pub_of_priv key) sgn) with | None -> assert_failure ("unpad failure " ^ show_key_size key) | Some dec -> assert_cs_equal msg dec @@ -118,9 +117,9 @@ let rsa_pkcs1_encode_selftest ~bits n = let rsa_pkcs1_sign_selftest n = let open Hash.SHA1 in "selftest" >:: times ~n @@ fun _ -> - let (key, _) = gen_rsa ~bits:(Rsa.PKCS1.min_key `SHA1) - and msg = Mirage_crypto_rng.generate 47 in - let pkey = Rsa.pub_of_priv key in + let key = gen_rsa ~bits:(Rsa.PKCS1.min_key `SHA1) + and msg = Mirage_crypto_rng.generate 47 in + let pkey = Rsa.pub_of_priv key in assert_bool "invert 1" Rsa.PKCS1.( verify ~key:pkey ~hashp:any (`Message msg) ~signature:(sign ~hash:`SHA1 ~key (`Digest (digest msg))) ); @@ -130,9 +129,9 @@ let rsa_pkcs1_sign_selftest n = let rsa_pkcs1_encrypt_selftest ~bits n = "selftest" >:: times ~n @@ fun _ -> - let (key, _) = gen_rsa ~bits - and msg = pkcs_message_for_bits bits in - let enc = Rsa.(PKCS1.encrypt ~key:(pub_of_priv key) msg) in + let key = gen_rsa ~bits + and msg = pkcs_message_for_bits bits in + let enc = Rsa.(PKCS1.encrypt ~key:(pub_of_priv key) msg) in match Rsa.PKCS1.decrypt ~key enc with | None -> assert_failure ("unpad failure " ^ show_key_size key) | Some dec -> assert_cs_equal msg dec @@ -143,9 +142,9 @@ let rsa_oaep_encrypt_selftest ~bits n = "selftest" >:: times ~n @@ fun _ -> let module H = (val (Hash.module_of (sample hashes))) in let module OAEP = Rsa.OAEP (H) in - let (key, _) = gen_rsa ~bits - and msg = Mirage_crypto_rng.generate (bits // 8 - 2 * H.digest_size - 2) in - let enc = OAEP.encrypt ~key:(Rsa.pub_of_priv key) msg in + let key = gen_rsa ~bits + and msg = Mirage_crypto_rng.generate (bits // 8 - 2 * H.digest_size - 2) in + let enc = OAEP.encrypt ~key:(Rsa.pub_of_priv key) msg in match OAEP.decrypt ~key enc with | None -> assert_failure "unpad failure" | Some dec -> assert_cs_equal msg dec ~msg:"recovery failure" @@ -154,9 +153,9 @@ let rsa_pss_sign_selftest ~bits n = let module Pss_sha1 = Rsa.PSS (Hash.SHA1) in let open Hash.SHA1 in "selftest" >:: times ~n @@ fun _ -> - let (key, _) = gen_rsa ~bits - and msg = Mirage_crypto_rng.generate 1024 in - let pkey = Rsa.pub_of_priv key in + let key = gen_rsa ~bits + and msg = Mirage_crypto_rng.generate 1024 in + let pkey = Rsa.pub_of_priv key in Pss_sha1.(verify ~key:pkey (`Message msg) ~signature:(sign ~key (`Digest (digest msg)))) |> assert_bool "invert 1" ;