Skip to content

Commit

Permalink
use Z.powm_sec for private key operations to avoid timing side channels
Browse files Browse the repository at this point in the history
  • Loading branch information
hannesm committed Feb 26, 2020
1 parent 287cd42 commit bcd10cc
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 13 deletions.
3 changes: 2 additions & 1 deletion mirage-crypto-pk.opam
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ build: [ ["dune" "subst"] {pinned}
["dune" "runtest" "-p" name "-j" jobs] {with-test} ]

depends: [
"conf-gmp-powm-sec" {build}
"ocaml" {>= "4.07.0"}
"dune" {>= "1.7"}
"dune-configurator" {>= "2.0.0"}
Expand All @@ -24,7 +25,7 @@ depends: [
"ocplib-endian"
"sexplib"
"ppx_sexp_conv"
"zarith"
"zarith" {>= "1.4"}
("mirage-no-xen" | "zarith-xen")
("mirage-no-solo5" | "zarith-freestanding")
]
7 changes: 3 additions & 4 deletions pk/dh.ml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ let bad_public_key { p; gg; _ } ggx =
ggx <= Z.one || ggx >= Z.(pred p) || ggx = gg

let key_of_secret_z ({ p; gg; _ } as group) x =
match Z.(powm gg x p) with
match Z.(powm_sec gg x p) with
| ggx when bad_public_key group ggx
-> raise Invalid_public_key
| ggx -> ({ x }, Numeric.Z.to_cstruct_be ggx)
Expand All @@ -62,17 +62,16 @@ let rec gen_key ?g ?bits ({ p; q; _ } as group) =
|> Rng.Z.gen_bits ?g ~msb:1 in
try key_of_secret_z group s with Invalid_public_key -> gen_key ?g ?bits group

(* No time-masking. Does it matter in case of ephemeral DH?? *)
let shared ({ p; _ } as group) { x } cs =
match Numeric.Z.of_cstruct_be cs with
| ggy when bad_public_key group ggy -> None
| ggy -> Some (Numeric.Z.to_cstruct_be (Z.powm ggy x p))
| ggy -> Some (Numeric.Z.to_cstruct_be (Z.powm_sec ggy x p))

(* Finds a safe prime with [p = 2q + 1] and [2^q = 1 mod p]. *)
let rec gen_group ?g bits =
let gg = Z.two
and (q, p) = Rng.safe_prime ?g (imax bits 1) in
if Z.(powm gg q p = one) then { p; gg; q = Some q } else gen_group ?g bits
if Z.(powm_sec gg q p = one) then { p; gg; q = Some q } else gen_group ?g bits

module Group = struct

Expand Down
9 changes: 5 additions & 4 deletions pk/dsa.ml
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ let params ?g size =
let e = Z.(pred p / q) in
until ((<>) Z.one) @@ fun () ->
let h = Rng.Z.gen_r ?g Z.(~$2) Z.(pred p) in
Z.(powm h e p) in
Z.(powm_sec h e p) in
(p, q, gg)

let generate ?g size =
let (p, q, gg) = params ?g size in
let x = Rng.Z.gen_r ?g Z.one q in
let y = Z.(powm gg x p) in
let y = Z.(powm_sec gg x p) in
{ p; q; gg; x; y }


Expand All @@ -79,14 +79,15 @@ let rec sign_z ?(mask = `Yes) ?k:k0 ~key:({ p; q; gg; x; _ } as key) z =
let k = match k0 with Some k -> k | None -> K_gen_sha256.z_gen ~key z in
let k' = Z.invert k q
and r = match expand_mask mask with
| `No -> Z.(powm gg k p mod q)
| `No -> Z.(powm_sec gg k p mod q)
| `Yes g ->
let m = Rng.Z.gen_r ?g Z.one q in
let m' = Z.invert m q in
Z.(powm (powm gg m p) (m' * k mod q) p mod q) in
Z.(powm_sec (powm_sec gg m p) (m' * k mod q) p mod q) in
let s = Z.(k' * (z + x * r) mod q) in
if r = Z.zero || s = Z.zero then sign_z ~mask ?k:k0 ~key z else (r, s)

(* verify uses public key, no need to time-mask the modular exponentiation *)
let verify_z ~key:({ p; q; gg; y }: pub ) (r, s) z =
let v () =
let w = Z.invert s q in
Expand Down
8 changes: 4 additions & 4 deletions pk/rsa.ml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ let rec priv_of_exp ?g ?(attempts=100) ~e ~d n =
if Z.(ax <> one && ax <> pred n && ax2 = one) then
Some ax
else go ax2 (i' - 1) in
Option.(go Z.(powm (Rng.Z.gen ?g n) t n) s >>| Z.(gcd n &. pred)) in
Option.(go Z.(powm_sec (Rng.Z.gen ?g n) t n) s >>| Z.(gcd n &. pred)) in
let err (k : _ format4 -> _) =
Z.(k "Rsa.priv_of_exp: e: %a, d: %a, n: %a" pp e pp d pp n) in
if attempts > 0 then
Expand All @@ -78,15 +78,15 @@ and priv_bits ({ n; _ } : priv) = Numeric.Z.bits n
let encrypt_unsafe ~key: ({ e; n } : pub) msg = Z.(powm msg e n)

let decrypt_unsafe ~key: ({ p; q; dp; dq; q'; _} : priv) c =
let m1 = Z.(powm c dp p)
and m2 = Z.(powm c dq q) in
let m1 = Z.(powm_sec c dp p)
and m2 = Z.(powm_sec c dq q) in
let h = Z.(erem (q' * (m1 - m2)) p) in
Z.(h * q + m2)

let decrypt_blinded_unsafe ?g ~key: ({ e; n; _} as key : priv) c =
let r = until (rprime n) (fun _ -> Rng.Z.gen_r ?g Z.two n) in
let r' = Z.(invert r n) in
let x = decrypt_unsafe ~key Z.(powm r e n * c mod n) in
let x = decrypt_unsafe ~key Z.(powm_sec r e n * c mod n) in
Z.(r' * x mod n)

let (encrypt_z, decrypt_z) =
Expand Down

0 comments on commit bcd10cc

Please sign in to comment.