forked from emillon/hacl-star-dune
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSharedDefs.ml
384 lines (323 loc) · 14.7 KB
/
SharedDefs.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
open Unsigned
(* We keep the API abstract over the type of buffer used in order to keep the
* possibility of swapping this implementation in the future or offering
* multiple such implementations. A past version of the library was
* built using Bigstring instead of Bytes. *)
module type Buffer = sig
type t
type buf
val empty: bytes
val size_uint32 : bytes -> uint32
val ctypes_buf : bytes -> buf
val size : bytes -> int
val equal : bytes -> bytes -> bool
val make : int -> bytes
val disjoint : bytes -> bytes -> bool
val sub : bytes -> int -> int -> bytes
val z_compare : bytes -> Z.t -> int
end
(** Abstract representation of buffers *)
module CBytes : Buffer with type t = Bytes.t and type buf = Bytes.t Ctypes.ocaml = struct
type t = Bytes.t
type buf = Bytes.t Ctypes.ocaml
let empty = Bytes.empty
let size_uint32 b = Unsigned.UInt32.of_int (Bytes.length b)
let ctypes_buf = Ctypes.ocaml_bytes_start
let size = Bytes.length
let equal = Bytes.equal
let make l = Bytes.make l '\x00'
let disjoint b1 b2 = b1 != b2
let sub = Bytes.sub
let z_compare b z = Z.compare (Z.of_bits (Bytes.to_string b)) z
end
(** Representation of [Bytes.t] buffers *)
module Hacl_Hash = struct
include Hacl_Hash_Base_bindings.Bindings(Hacl_Hash_Base_stubs)
include Hacl_Hash_MD5_bindings.Bindings(Hacl_Hash_MD5_stubs)
include Hacl_Hash_SHA1_bindings.Bindings(Hacl_Hash_SHA1_stubs)
include Hacl_Hash_SHA2_bindings.Bindings(Hacl_Hash_SHA2_stubs)
include Hacl_Hash_Blake2_bindings.Bindings(Hacl_Hash_Blake2_stubs)
end
module Hacl_Spec = Hacl_Spec_bindings.Bindings(Hacl_Spec_stubs)
let pow2 n = Z.(pow ~$2) n
module AEADDefs = struct
open Hacl_Spec
type alg =
| AES128_GCM
| AES256_GCM
| CHACHA20_POLY1305
let alg_definition = function
| AES128_GCM -> spec_Agile_AEAD_alg_Spec_Agile_AEAD_AES128_GCM
| AES256_GCM -> spec_Agile_AEAD_alg_Spec_Agile_AEAD_AES256_GCM
| CHACHA20_POLY1305 -> spec_Agile_AEAD_alg_Spec_Agile_AEAD_CHACHA20_POLY1305
let key_length = function
(* specs/Spec.Agile.AEAD.key_length *)
| AES128_GCM -> 16
| AES256_GCM -> 32
| CHACHA20_POLY1305 -> 32
let tag_length = function
(* specs/Spec.Agile.AEAD.tag_length *)
| AES128_GCM
| AES256_GCM
| CHACHA20_POLY1305 -> 16
let check_iv_length len = function
(* specs/Spec.Agile.AEAD.iv_length *)
| AES128_GCM
| AES256_GCM -> len > 0 && Z.((of_int 8) * (of_int len) < pow2 64)
| CHACHA20_POLY1305 -> len = 12
let check_max_pt_length len = function
(* specs/Spec.Agile.AEAD.max_length *)
| AES128_GCM
| AES256_GCM -> Z.(of_int len < pow2 32)
| CHACHA20_POLY1305 -> Z.(of_int len < pow2 32 - of_int 16)
let check_sizes ~alg ~iv_len ~tag_len ~ad_len ~pt_len ~ct_len =
(* providers/EverCrypt.AEAD.encrypt_st *)
assert (check_iv_length iv_len alg);
assert (tag_len = tag_length alg);
assert (check_max_pt_length pt_len alg);
assert Z.(of_int ad_len <= pow2 31);
assert (pt_len = ct_len)
end
module HashDefs = struct
open Hacl_Spec
type deprecated_alg =
| SHA1
| MD5 [@@deprecated]
type alg =
| SHA2_224
| SHA2_256
| SHA2_384
| SHA2_512
| BLAKE2b
| BLAKE2s
| Legacy of deprecated_alg
let alg_definition = function
| SHA2_224 -> spec_Hash_Definitions_hash_alg_Spec_Hash_Definitions_SHA2_224
| SHA2_256 -> spec_Hash_Definitions_hash_alg_Spec_Hash_Definitions_SHA2_256
| SHA2_384 -> spec_Hash_Definitions_hash_alg_Spec_Hash_Definitions_SHA2_384
| SHA2_512 -> spec_Hash_Definitions_hash_alg_Spec_Hash_Definitions_SHA2_512
| BLAKE2b -> spec_Hash_Definitions_hash_alg_Spec_Hash_Definitions_Blake2B
| BLAKE2s -> spec_Hash_Definitions_hash_alg_Spec_Hash_Definitions_Blake2S
| Legacy SHA1 -> spec_Hash_Definitions_hash_alg_Spec_Hash_Definitions_SHA1
| Legacy MD5 -> spec_Hash_Definitions_hash_alg_Spec_Hash_Definitions_MD5
let digest_len alg =
UInt32.to_int (Hacl_Hash.hacl_Hash_Definitions_hash_len (alg_definition alg))
let check_digest_len alg len =
assert (len = digest_len alg)
let max_input_len = function
(* specs/Spec.Hash.Definitions.max_input_length *)
| Legacy SHA1
| Legacy MD5
| SHA2_224
| SHA2_256 -> pow2 61
| SHA2_384
| SHA2_512 -> pow2 125
| BLAKE2b -> pow2 128
| BLAKE2s -> pow2 64
let check_max_input_len alg len =
assert Z.(of_int len < max_input_len alg)
let block_len alg =
UInt32.to_int (Hacl_Hash.hacl_Hash_Definitions_block_len (alg_definition alg))
let check_key_len alg len =
assert Z.(of_int len + of_int (block_len alg) < max_input_len alg)
end
module type Chacha20_Poly1305_generic = sig
type bytes
val encrypt: key:bytes -> iv:bytes -> ad:bytes -> pt:bytes -> bytes * bytes
(** [encrypt key iv ad pt] takes a [key], an initial value [iv], additional data
[ad], and plaintext [pt] and returns a tuple containing the encrypted [pt] and the
authentication tag for the plaintext and the associated data. *)
val decrypt: key:bytes -> iv:bytes -> ad:bytes -> ct:bytes -> tag:bytes -> bytes option
(** [decrypt key iv ad ct tag] takes a [key], the initial value [iv], additional
data [ad], ciphertext [ct], and authentication tag [tag], and, if successful,
returns the decrypted [ct]. *)
(** Versions of these functions which write their output in a buffer passed in as
an argument *)
module Noalloc : sig
val encrypt: key:bytes -> iv:bytes -> ad:bytes -> pt:bytes -> ct:bytes -> tag:bytes -> unit
(** [encrypt key iv ad pt ct tag] takes a [key], an initial value [iv], additional data
[ad], and plaintext [pt], as well as output buffers [ct], which will
contain the encrypted [pt], and [tag], which will contain the authentication tag for
the plaintext and the associated data. *)
val decrypt: key:bytes -> iv:bytes -> ad:bytes -> ct:bytes -> tag:bytes -> pt:bytes -> bool
(** [decrypt key iv ad ct tag pt] takes a [key], the initial value [iv], additional
data [ad], ciphertext [ct], and authentication tag [tag], as well as output buffer [pt],
which, if successful, will contain the decrypted [ct]. *)
end
end
module type Curve25519_generic = sig
(** See {{:https://hacl-star.github.io/HaclECDH.html#hacl-curve25519} here} for detailed
usage instructions.
*)
type bytes
val secret_to_public : sk:bytes -> bytes
(** [secret_to_public sk] takes a 32-byte secret key [sk] and returns the corresponding
32-byte ECDH public key. *)
val ecdh : sk:bytes -> pk:bytes -> bytes option
(** [ecdh sk pk] takes a 32-byte secret key [sk] and another party's 32-byte public
key and returns the 32-byte ECDH shared key. *)
val scalarmult : scalar:bytes -> point:bytes -> bytes
(** [scalarmult scalar point] performs scalar multiplication over the curve. Buffers
are 32-byte long and must be distinct. *)
(** Versions of these functions which write their output in a buffer passed in as
an argument *)
module Noalloc : sig
val secret_to_public : sk:bytes -> pk:bytes -> unit
(** [secret_to_public sk pk] takes a 32-byte secret key [sk] and writes the corresponding
32-byte ECDH public key in [pk]. Buffers [pk] and [sk] must be distinct. *)
val ecdh : sk:bytes -> pk:bytes -> shared:bytes -> bool
(** [ecdh sk pk shared] takes a 32-byte secret key [sk] and another party's 32-byte public
key and writes the 32-byte ECDH shared key in [shared]. Buffer [shared] must be distinct from
[pk] and [sk]. *)
val scalarmult : scalar:bytes -> point:bytes -> result:bytes -> unit
(** [scalarmult scalar point] performs scalar multiplication over the curve. Buffers
are 32-byte long and must be distinct. *)
end
end
module type EdDSA_generic = sig
(** See {{:https://hacl-star.github.io/HaclSig.html} here} for detailed
usage instructions.
*)
type bytes
(** {1 EdDSA} *)
val secret_to_public : sk:bytes -> bytes
(** [secret_to_public sk] takes a secret key [sk] and returns the corresponding
public key. *)
val sign : sk:bytes -> msg:bytes -> bytes
(** [sign sk msg] takes secret key [sk] and message [msg] and returns
the Ed25519 signature. *)
val verify : pk:bytes -> msg:bytes -> signature:bytes -> bool
(** [verify pk msg signature] takes public key [pk], message [msg] and verifies the
Ed25519 signature, returning true if valid. *)
(** {1 EdDSA Expanded Signing} *)
val expand_keys : sk:bytes -> bytes
(** [expand_keys sk] takes secret key [sk] and returns the expanded secret key. *)
val sign_expanded : ks:bytes -> msg:bytes -> bytes
(** [sign_expanded ks msg signature] takes expanded secret key [ks] and message [msg] and
returns the Ed25519 signature. *)
(** Versions of these functions which write their output in a buffer passed in as
an argument *)
module Noalloc : sig
(** Buffers have the following size constraints:
- [sk], [pk]: 32 bytes
- [signature]: 64 bytes
{1 EdDSA}
Note: The [verify] function does not return a buffer so it has no been duplicated here.
*)
val secret_to_public : sk:bytes -> pk:bytes -> unit
(** [secret_to_public sk pk] takes a secret key [sk] and writes the corresponding
public key in [pk]. Buffers [pk] and [sk] must be distinct. *)
val sign : sk:bytes -> msg:bytes -> signature:bytes -> unit
(** [sign sk msg signature] takes secret key [sk] and message [msg] and writes
the Ed25519 signature in [signature]. *)
(** {1 EdDSA Expanded Signing}
The buffer [ks] containing the expanded secret key must be 96 bytes long.
*)
val expand_keys : sk:bytes -> ks:bytes -> unit
(** [expand_keys sk ks] takes secret key [sk] and writes the expanded secret key in [ks]. *)
val sign_expanded : ks:bytes -> msg:bytes -> signature:bytes -> unit
(** [sign_expanded ks msg signature] takes expanded secret key [ks] and message [msg] and writes
the Ed25519 signature in [signature]. *)
end
end
module type HashFunction_generic = sig
type bytes
val hash : bytes -> bytes
(** [hash msg] returns the hash of [msg]. *)
(** Version of this function which writes its output in a buffer passed in as
an argument *)
module Noalloc : sig
val hash : msg:bytes -> digest:bytes -> unit
(** [hash msg digest] hashes [msg] and outputs the result in [digest]. *)
end
end
module type MAC_generic = sig
(** For Poly1305, buffers have the following size constraints:
- [key]: 32 bytes
- output buffer: 16 bytes
For HMAC with SHA-2, the output buffer is the same size as the digest size of
the corresponding hash function (see {{!EverCrypt.Hash} here}). For HMAC with BLAKE2,
the output buffer is 64 bytes for BLAKE2b and 32 bytes for BLAKE2s.
*)
type bytes
val mac : key:bytes -> msg:bytes -> bytes
(** [mac key msg] computes the MAC of [msg] using key [key]. *)
(** Version of this function which writes its output in a buffer passed in as
an argument *)
module Noalloc : sig
val mac : key:bytes -> msg:bytes -> tag:bytes -> unit
(** [mac key msg tag] computes the MAC of [msg] using key [key] and writes the result in [tag].
The `tag` buffer needs to satisfy the size requirements for the output buffer. *)
end
end
module type HKDF_generic = sig
(** Buffers have the following size constraints with respect to the digest size of the underlying
hash function, [digest_len]:
- [prk]: = [digest_len]
- [okm]: <= 255 * [digest_len]
*)
type bytes
val extract: salt:bytes -> ikm:bytes -> bytes
(** [extract salt ikm] computes a pseudorandom key using input key material [ikm] and
salt [salt]. *)
val expand: prk:bytes -> info:bytes -> size:int -> bytes
(** [expand prk info size] expands the pseudorandom key [prk], taking the info string [info] into
account and returns a buffer of [size] bytes. *)
(** Versions of these functions which write their output in a buffer passed in as
an argument *)
module Noalloc : sig
val extract: salt:bytes -> ikm:bytes -> prk:bytes -> unit
(** [extract salt ikm prk] computes a pseudorandom key [prk] using input key material [ikm] and
salt [salt]. *)
val expand: prk:bytes -> info:bytes -> okm:bytes -> unit
(** [expand prk info okm] expands the pseudorandom key [prk], taking the info string [info] into
account, and writes the output key material in [okm]. *)
end
end
module type ECDSA_generic = sig
(** Buffers have the following size constraints:
- [pk]: 64 bytes, corresponding to the "raw" representation of an elliptic curve point (see {!section:points})
- [sk], [k]: 32 bytes
- [signature]: 64 bytes
- [msg]: no size requirement for variants using SHA-2 hashing (see {!section:ecdsa})
*)
type bytes
val sign : sk:bytes -> msg:bytes -> k:bytes -> bytes option
(** [sign sk msg k] attempts to sign the message [msg] with secret key [sk] and
signing secret [k] and returns the signature if successful. *)
val verify : pk:bytes -> msg:bytes -> signature:bytes -> bool
(** [verify pk msg signature] checks the [signature] of [msg] using public key [pk] and returns
true if it is valid. *)
(** Versions of these functions which write their output in a buffer passed in as
an argument *)
module Noalloc : sig
val sign : sk:bytes -> msg:bytes -> k:bytes -> signature:bytes -> bool
(** [sign sk msg k signature] attempts to sign the message [msg] with secret key [sk] and
signing secret [k]. If successful, the signature is written in [signature] and the
function returns true. *)
end
end
module type Blake2_generic = sig
(** Buffers have the following size constraints:
- [key]: <= 64 bytes for BLAKE2b, <= 32 bytes for BLAKE2s
- [digest]: non-zero, <= 64 bytes for BLAKE2b, <= 32 bytes for BLAKE2s *)
type bytes
val hash : ?key:bytes -> bytes -> int -> bytes
(** [hash ?key msg size] hashes [msg] and returns a digest of length [size].
An optional [key] argument can be passed for keyed hashing. *)
(** Version of this function which writes its output in a buffer passed in as
an argument *)
module Noalloc : sig
val hash : key:bytes -> msg:bytes -> digest:bytes -> unit
(** [hash key msg digest] hashes [msg] and outputs the result in [digest].
A non-empty [key] can be passed for keyed hashing. *)
end
end
module type Chacha20_Poly1305 = Chacha20_Poly1305_generic with type bytes = CBytes.t
module type Curve25519 = Curve25519_generic with type bytes = CBytes.t
module type EdDSA = EdDSA_generic with type bytes = CBytes.t
module type HashFunction = HashFunction_generic with type bytes = CBytes.t
module type MAC = MAC_generic with type bytes = CBytes.t
module type HKDF = HKDF_generic with type bytes = CBytes.t
module type ECDSA = ECDSA_generic with type bytes = CBytes.t
module type Blake2 = Blake2_generic with type bytes = CBytes.t