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

adapt to mirage-crypto 1.0.0 API changes #73

Merged
merged 1 commit into from
Aug 28, 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
8 changes: 4 additions & 4 deletions awa.opam
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ build: [
depends: [
"ocaml" {>= "4.10.0"}
"dune" {>= "2.7"}
"mirage-crypto" {>= "0.8.1"}
"mirage-crypto-rng" {>= "0.11.0"}
"mirage-crypto" {>= "1.0.0"}
"mirage-crypto-rng" {>= "1.0.0"}
"mirage-crypto-pk"
"mirage-crypto-ec" {>= "0.10.0"}
"x509" {>= "0.15.2"}
"mirage-crypto-ec" {>= "1.0.0"}
"x509" {>= "1.0.0"}
"cstruct" {>= "6.0.0"}
"cstruct-unix"
"mtime" {>= "1.0.0"}
Expand Down
12 changes: 7 additions & 5 deletions lib/auth.ml
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,24 @@ let by_password name password db =
| None -> false
| Some user -> match user.password with
| Some password' ->
let a = Mirage_crypto.Hash.digest `SHA256 (Cstruct.of_string password')
and b = Mirage_crypto.Hash.digest `SHA256 (Cstruct.of_string password) in
Eqaf_cstruct.equal a b
let open Digestif.SHA256 in
let a = to_raw_string (digest_string password')
and b = to_raw_string (digest_string password) in
Eqaf.equal a b
| None -> false

let to_hash name alg pubkey session_id service =
let open Wire in
put_cstring session_id (Dbuf.create ()) |>
put_string session_id (Dbuf.create ()) |>
put_message_id Ssh.MSG_USERAUTH_REQUEST |>
put_string name |>
put_string service |>
put_string "publickey" |>
put_bool true |>
put_string (Hostkey.alg_to_string alg) |>
put_pubkey pubkey |>
Dbuf.to_cstruct
Dbuf.to_cstruct |>
Cstruct.to_string

let sign name alg key session_id service =
let data = to_hash name alg (Hostkey.pub_of_priv key) session_id service in
Expand Down
51 changes: 25 additions & 26 deletions lib/cipher.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)

open Mirage_crypto.Cipher_block.AES
open Mirage_crypto

type t =
| Plaintext
Expand All @@ -32,9 +32,9 @@ let aead = function

type cipher_key =
| Plaintext_key
| Aes_ctr_key of (CTR.key * CTR.ctr)
| Aes_cbc_key of (CBC.key * Cstruct.t)
| Chacha20_poly1305_key of (Mirage_crypto.Chacha20.key * Mirage_crypto.Chacha20.key)
| Aes_ctr_key of (AES.CTR.key * AES.CTR.ctr)
| Aes_cbc_key of (AES.CBC.key * string)
| Chacha20_poly1305_key of (Chacha20.key * Chacha20.key)

type key = {
cipher : t;
Expand Down Expand Up @@ -74,25 +74,24 @@ let key_len = function

let iv_len = function
| Plaintext -> 0
| Aes128_ctr | Aes192_ctr | Aes256_ctr -> CTR.block_size
| Aes128_cbc | Aes192_cbc | Aes256_cbc -> CBC.block_size
| Aes128_ctr | Aes192_ctr | Aes256_ctr -> AES.CTR.block_size
| Aes128_cbc | Aes192_cbc | Aes256_cbc -> AES.CBC.block_size
| Chacha20_poly1305 -> 0

let block_len = function
| Plaintext -> 8
| Aes128_ctr | Aes192_ctr | Aes256_ctr -> CTR.block_size
| Aes128_cbc | Aes192_cbc | Aes256_cbc -> CBC.block_size
| Aes128_ctr | Aes192_ctr | Aes256_ctr -> AES.CTR.block_size
| Aes128_cbc | Aes192_cbc | Aes256_cbc -> AES.CBC.block_size
| Chacha20_poly1305 -> 8

let mac_len = function
| Chacha20_poly1305 -> Mirage_crypto.Poly1305.mac_size
| Chacha20_poly1305 -> Poly1305.mac_size
| _ -> 0

let known s = Result.is_ok (of_string s)

(* For some reason Nocrypto CTR modifies ctr in place, CBC returns next *)
(* For some reason mirage-crypto CTR modifies ctr in place, CBC returns next *)
let enc_dec enc ~len seq cipher buf =
let open Mirage_crypto.Cipher_block in
match cipher.cipher_key with
| Plaintext_key -> Ok (buf, cipher)
| Aes_ctr_key (key, iv) ->
Expand All @@ -111,39 +110,39 @@ let enc_dec enc ~len seq cipher buf =
Ok (buf, cipher)
| Chacha20_poly1305_key (len_key, key) ->
let nonce =
let b = Cstruct.create 8 in
Cstruct.BE.set_uint64 b 0 (Int64.of_int32 seq);
b
let b = Bytes.create 8 in
Bytes.set_int64_be b 0 (Int64.of_int32 seq);
Bytes.unsafe_to_string b
in
let c_len b = Mirage_crypto.Chacha20.crypt ~key:len_key ~nonce b in
let c_data b = Mirage_crypto.Chacha20.crypt ~key ~ctr:1L ~nonce b in
let c_len b = Chacha20.crypt ~key:len_key ~nonce b in
let c_data b = Chacha20.crypt ~key ~ctr:1L ~nonce b in
let mac data =
let key = Mirage_crypto.Chacha20.crypt ~key ~nonce (Cstruct.create 32) in
Mirage_crypto.Poly1305.mac ~key data
let key = Chacha20.crypt ~key ~nonce (String.make 32 '\000') in
Poly1305.mac ~key data
in
if enc then
let lbuf, msg = Cstruct.split buf 4 in
let lbuf, msg = String.sub buf 0 4, String.sub buf 4 (String.length buf - 4) in
let enc_len = c_len lbuf in
let enc_msg = c_data msg in
let out = Cstruct.append enc_len enc_msg in
let out = enc_len ^ enc_msg in
let tag = mac out in
Ok (Cstruct.append out tag, cipher)
Ok (out ^ tag, cipher)
else
begin
if len then
Ok (c_len buf, cipher)
else
let c, tag =
let off = Cstruct.length buf - Mirage_crypto.Poly1305.mac_size in
Cstruct.split buf off
let off = String.length buf - Poly1305.mac_size in
String.sub buf 0 off, String.sub buf off (String.length buf - off)
in
let ctag = mac c in
let enc_len, enc_msg = Cstruct.split c 4 in
let enc_len, enc_msg = String.sub c 0 4, String.sub c 4 (String.length c - 4) in
let dec_len = c_len enc_len
and dec_msg = c_data enc_msg
in
if Cstruct.equal ctag tag then
Ok (Cstruct.append dec_len dec_msg, cipher)
if String.equal ctag tag then
Ok (dec_len ^ dec_msg, cipher)
else
Error "tag verification failed"
end
Expand Down
4 changes: 2 additions & 2 deletions lib/client.ml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type state =

type t = {
state : state ;
session_id : Cstruct.t option;
session_id : string option;
keys_ctos : Kex.keys;
keys_stoc : Kex.keys;
keying : bool;
Expand Down Expand Up @@ -226,7 +226,7 @@ let handle_kexdh_gex_group t v_c ckex v_s skex neg min n max p gg =
let bits = modulus_size group in
if Int32.to_int min <= bits && bits <= Int32.to_int max then
let secret, shared = gen_key group in
let pub = Mirage_crypto_pk.Z_extra.of_cstruct_be shared in
let pub = Mirage_crypto_pk.Z_extra.of_octets_be shared in
let state = Negotiated_gex (v_c, ckex, v_s, skex, neg, min, n, max, p, gg, secret, pub) in
Ok ({ t with state = Gex state }, [ Ssh.Msg_kexdh_gex_init pub ], [])
else
Expand Down
2 changes: 1 addition & 1 deletion lib/dune
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(library
(name awa)
(public_name awa)
(libraries eqaf.cstruct cstruct mirage-crypto mirage-crypto-rng mirage-crypto-pk zarith x509 mtime logs base64 mirage-crypto-ec))
(libraries eqaf cstruct mirage-crypto mirage-crypto-rng mirage-crypto-pk zarith x509 mtime logs base64 mirage-crypto-ec))
24 changes: 12 additions & 12 deletions lib/hmac.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)

open Mirage_crypto.Hash
open Digestif

type t =
| Plaintext
Expand All @@ -26,8 +26,8 @@ type t =
| Sha2_512

type key = {
hmac : t; (* Hmac algorithm *)
key : Cstruct.t; (* The actual hmac key *)
hmac : t; (* Hmac algorithm *)
key : string; (* The actual hmac key *)
}

let to_string = function
Expand Down Expand Up @@ -74,16 +74,16 @@ let preferred = [ Md5; Sha1; Sha2_256;

let hmacv hmac ~key data =
let take_96 buf =
if Cstruct.length buf < 12 then
if String.length buf < 12 then
failwith "digest is too short."
else
Cstruct.sub buf 0 12
String.sub buf 0 12
in
match hmac with
| Plaintext -> Cstruct.create 0
| Md5 -> MD5.hmaci ~key (fun f -> List.iter f data)
| Md5_96 -> MD5.hmaci ~key (fun f -> List.iter f data) |> take_96
| Sha1 -> SHA1.hmaci ~key (fun f -> List.iter f data)
| Sha1_96 -> SHA1.hmaci ~key (fun f -> List.iter f data) |> take_96
| Sha2_256 -> SHA256.hmaci ~key (fun f -> List.iter f data)
| Sha2_512 -> SHA512.hmaci ~key (fun f -> List.iter f data)
| Plaintext -> ""
| Md5 -> MD5.(hmaci_string ~key (fun f -> List.iter f data) |> to_raw_string)
| Md5_96 -> MD5.(hmaci_string ~key (fun f -> List.iter f data) |> to_raw_string |> take_96)
| Sha1 -> SHA1.(hmaci_string ~key (fun f -> List.iter f data) |> to_raw_string)
| Sha1_96 -> SHA1.(hmaci_string ~key (fun f -> List.iter f data) |> to_raw_string |> take_96)
| Sha2_256 -> SHA256.(hmaci_string ~key (fun f -> List.iter f data) |> to_raw_string)
| Sha2_512 -> SHA512.(hmaci_string ~key (fun f -> List.iter f data) |> to_raw_string)
6 changes: 3 additions & 3 deletions lib/hostkey.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ let pub_eq a b = match a, b with
| Rsa_pub rsa, Rsa_pub rsa' ->
Z.equal rsa.Rsa.e rsa'.Rsa.e && Z.equal rsa.Rsa.n rsa'.Rsa.n
| Ed25519_pub e, Ed25519_pub e' ->
Cstruct.equal
(Mirage_crypto_ec.Ed25519.pub_to_cstruct e)
(Mirage_crypto_ec.Ed25519.pub_to_cstruct e')
String.equal
(Mirage_crypto_ec.Ed25519.pub_to_octets e)
(Mirage_crypto_ec.Ed25519.pub_to_octets e')
| _ -> false

let pub_of_priv = function
Expand Down
61 changes: 32 additions & 29 deletions lib/kex.ml
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ let group_of_alg = function
let hash_of_alg = function
| Diffie_hellman_group_exchange_sha256
| Diffie_hellman_group14_sha256
| Curve25519_sha256 -> Mirage_crypto.Hash.module_of `SHA256
| Curve25519_sha256 -> Digestif.module_of_hash' `SHA256
| Diffie_hellman_group_exchange_sha1
| Diffie_hellman_group14_sha1
| Diffie_hellman_group1_sha1 -> Mirage_crypto.Hash.module_of `SHA1
| Ecdh_sha2_nistp256 -> Mirage_crypto.Hash.module_of `SHA256
| Ecdh_sha2_nistp384 -> Mirage_crypto.Hash.module_of `SHA384
| Ecdh_sha2_nistp521 -> Mirage_crypto.Hash.module_of `SHA512
| Diffie_hellman_group1_sha1 -> Digestif.module_of_hash' `SHA1
| Ecdh_sha2_nistp256 -> Digestif.module_of_hash' `SHA256
| Ecdh_sha2_nistp384 -> Digestif.module_of_hash' `SHA384
| Ecdh_sha2_nistp521 -> Digestif.module_of_hash' `SHA512

let supported =
[ Curve25519_sha256 ;
Expand All @@ -114,7 +114,7 @@ let supported =

let make_kexinit ?ext_info host_key_algs algs () =
let k =
{ cookie = Mirage_crypto_rng.generate 16;
{ cookie = Cstruct.of_string (Mirage_crypto_rng.generate 16);
kex_algs = List.map alg_to_string algs;
ext_info;
server_host_key_algs = List.map Hostkey.alg_to_string host_key_algs;
Expand Down Expand Up @@ -261,7 +261,7 @@ let make_plaintext () =
{ cipher = Cipher.{ cipher = Plaintext;
cipher_key = Plaintext_key };
mac = Hmac.{ hmac = Plaintext;
key = Cstruct.create 0 };
key = "" };
seq = Int32.zero ;
tx_rx = Int64.zero }

Expand Down Expand Up @@ -300,35 +300,34 @@ let derive_keys digesti k h session_id neg now =
let cipher_stoc = neg.encryption_alg_stoc in
let mac_ctos = neg.mac_alg_ctos in
let mac_stoc = neg.mac_alg_stoc in
let k = Wire.(Dbuf.to_cstruct @@ put_mpint k (Dbuf.create ())) in
let k = Cstruct.to_string (Wire.(Dbuf.to_cstruct @@ put_mpint k (Dbuf.create ()))) in
let hash ch need =
let rec expand kn =
if (Cstruct.length kn) >= need then
if String.length kn >= need then
kn
else
let kn' = digesti (fun f -> List.iter f [k; h; kn]) in
expand (Cstruct.append kn kn')
expand (kn ^ kn')
in
let x = Cstruct.create 1 in
Cstruct.set_char x 0 ch;
let x = String.make 1 ch in
let k1 = digesti (fun f -> List.iter f [k; h; x; session_id]) in
Cstruct.sub (expand k1) 0 need
String.sub (expand k1) 0 need
in
let key_of cipher iv secret =
let open Mirage_crypto.Cipher_block in
let open Mirage_crypto in
let open Cipher in
match cipher with
| Plaintext -> invalid_arg "Deriving plaintext, abort at all costs"
| Aes128_ctr | Aes192_ctr | Aes256_ctr ->
let iv = AES.CTR.ctr_of_cstruct iv in
let iv = AES.CTR.ctr_of_octets iv in
{ cipher;
cipher_key = Aes_ctr_key ((AES.CTR.of_secret secret), iv) }
| Aes128_cbc | Aes192_cbc | Aes256_cbc ->
{ cipher;
cipher_key = Aes_cbc_key ((AES.CBC.of_secret secret), iv) }
| Chacha20_poly1305 ->
assert (Cstruct.length secret = 64);
let d, l = Cstruct.split secret 32 in
assert (String.length secret = 64);
let d, l = String.sub secret 0 32, String.sub secret 32 32 in
let lkey = Mirage_crypto.Chacha20.of_secret l
and key = Mirage_crypto.Chacha20.of_secret d
in
Expand Down Expand Up @@ -359,7 +358,7 @@ module Dh = struct

let derive_keys k h session_id neg now =
let (module H) = hash_of_alg neg.kex_alg in
derive_keys H.digesti k h session_id neg now
derive_keys (fun ds -> H.(to_raw_string (digesti_string ds))) k h session_id neg now

let compute_hash ?(signed = false) neg ~v_c ~v_s ~i_c ~i_s ~k_s ~e ~f ~k =
let (module H) = hash_of_alg neg.kex_alg in
Expand All @@ -373,7 +372,9 @@ module Dh = struct
put_mpint ~signed f |>
put_mpint k |>
Dbuf.to_cstruct |>
H.digest
Cstruct.to_string |>
H.digest_string |>
H.to_raw_string

let compute_hash_gex neg ~v_c ~v_s ~i_c ~i_s ~k_s ~min ~n ~max ~p ~g ~e ~f ~k =
let (module H) = hash_of_alg neg.kex_alg in
Expand All @@ -392,37 +393,39 @@ module Dh = struct
put_mpint f |>
put_mpint k |>
Dbuf.to_cstruct |>
H.digest
Cstruct.to_string |>
H.digest_string |>
H.to_raw_string

let secret_pub alg =
let secret, pub = Mirage_crypto_pk.Dh.gen_key (group_of_alg alg) in
secret, Mirage_crypto_pk.Z_extra.of_cstruct_be pub
secret, Mirage_crypto_pk.Z_extra.of_octets_be pub

let shared secret recv =
let r = Mirage_crypto_pk.Z_extra.to_cstruct_be recv in
let r = Mirage_crypto_pk.Z_extra.to_octets_be recv in
let* shared =
guard_some (Mirage_crypto_pk.Dh.shared secret r)
"Can't compute shared secret"
in
Ok (Mirage_crypto_pk.Z_extra.of_cstruct_be shared)
Ok (Mirage_crypto_pk.Z_extra.of_octets_be shared)

let ec_secret_pub = function
| Curve25519_sha256 ->
let secret, pub = Mirage_crypto_ec.X25519.gen_key () in
`Ed25519 secret, Mirage_crypto_pk.Z_extra.of_cstruct_be pub
`Ed25519 secret, Mirage_crypto_pk.Z_extra.of_octets_be pub
| Ecdh_sha2_nistp256 ->
let secret, pub = Mirage_crypto_ec.P256.Dh.gen_key () in
`P256 secret, Mirage_crypto_pk.Z_extra.of_cstruct_be pub
`P256 secret, Mirage_crypto_pk.Z_extra.of_octets_be pub
| Ecdh_sha2_nistp384 ->
let secret, pub = Mirage_crypto_ec.P384.Dh.gen_key () in
`P384 secret, Mirage_crypto_pk.Z_extra.of_cstruct_be pub
`P384 secret, Mirage_crypto_pk.Z_extra.of_octets_be pub
| Ecdh_sha2_nistp521 ->
let secret, pub = Mirage_crypto_ec.P521.Dh.gen_key () in
`P521 secret, Mirage_crypto_pk.Z_extra.of_cstruct_be pub
`P521 secret, Mirage_crypto_pk.Z_extra.of_octets_be pub
| _ -> assert false

let ec_shared secret recv =
let r = Mirage_crypto_pk.Z_extra.to_cstruct_be recv in
let r = Mirage_crypto_pk.Z_extra.to_octets_be recv in
let* shared =
Result.map_error
(Fmt.to_to_string Mirage_crypto_ec.pp_error)
Expand All @@ -432,7 +435,7 @@ module Dh = struct
| `P384 secret -> Mirage_crypto_ec.P384.Dh.key_exchange secret r
| `P521 secret -> Mirage_crypto_ec.P521.Dh.key_exchange secret r)
in
Ok (Mirage_crypto_pk.Z_extra.of_cstruct_be shared)
Ok (Mirage_crypto_pk.Z_extra.of_octets_be shared)

let generate alg peer_pub =
let secret, my_pub = secret_pub alg in
Expand Down
Loading