forked from emillon/hacl-star-dune
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSharedFunctors.ml
402 lines (386 loc) · 13.9 KB
/
SharedFunctors.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
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
open Unsigned
open SharedDefs
open AutoConfig2
let check_reqs = List.iter (fun x -> assert (has_feature x))
module Make_Chacha20_Poly1305_generic (C: Buffer)
(Impl : sig
val reqs : feature list
val encrypt : C.buf -> C.buf -> uint32 -> C.buf -> uint32 -> C.buf -> C.buf -> C.buf -> unit
val decrypt : C.buf -> C.buf -> uint32 -> C.buf -> uint32 -> C.buf -> C.buf -> C.buf -> uint32
end)
= struct
type bytes = C.t
open AEADDefs
let alg = CHACHA20_POLY1305
module Noalloc = struct
let encrypt ~key ~iv ~ad ~pt ~ct ~tag =
check_reqs Impl.reqs;
(* code/chacha20poly1305/Hacl.Impl.Chacha20Poly1305.aead_encrypt_st *)
check_sizes ~alg ~iv_len:(C.size iv) ~tag_len:(C.size tag)
~ad_len:(C.size ad)~pt_len:(C.size pt) ~ct_len:(C.size ct);
assert (C.disjoint key ct);
assert (C.disjoint iv ct);
assert (C.disjoint key tag);
assert (C.disjoint iv tag);
assert (C.disjoint ct tag);
assert (C.disjoint ad ct);
Impl.encrypt (C.ctypes_buf key) (C.ctypes_buf iv) (C.size_uint32 ad) (C.ctypes_buf ad)
(C.size_uint32 pt) (C.ctypes_buf pt) (C.ctypes_buf ct) (C.ctypes_buf tag)
let decrypt ~key ~iv ~ad ~ct ~tag ~pt =
check_reqs Impl.reqs;
(* code/chacha20poly1305/Hacl.Impl.Chacha20Poly1305.aead_decrypt_st *)
check_sizes ~alg ~iv_len:(C.size iv) ~tag_len:(C.size tag)
~ad_len:(C.size ad)~pt_len:(C.size pt) ~ct_len:(C.size ct);
let result = Impl.decrypt (C.ctypes_buf key) (C.ctypes_buf iv) (C.size_uint32 ad) (C.ctypes_buf ad)
(C.size_uint32 pt) (C.ctypes_buf pt) (C.ctypes_buf ct) (C.ctypes_buf tag)
in
UInt32.to_int result = 0
end
let encrypt ~key ~iv ~ad ~pt =
let ct = C.make (C.size pt) in
let tag = C.make (tag_length alg) in
Noalloc.encrypt ~key ~iv ~ad ~pt ~ct ~tag;
(ct, tag)
let decrypt ~key ~iv ~ad ~ct ~tag =
let pt = C.make (C.size ct) in
if Noalloc.decrypt ~key ~iv ~ad ~ct ~tag ~pt then
Some pt
else
None
end
module Make_Curve25519_generic (C: Buffer)
(Impl : sig
val reqs : feature list
val secret_to_public : C.buf -> C.buf -> unit
val scalarmult : C.buf -> C.buf -> C.buf -> unit
val ecdh : C.buf -> C.buf -> C.buf -> bool
end)
= struct
type bytes = C.t
module Noalloc = struct
let secret_to_public ~sk ~pk =
check_reqs Impl.reqs;
(* Hacl.Impl.Curve25519.Generic.secret_to_public_st *)
assert (C.disjoint pk sk);
assert (C.size pk = 32);
assert (C.size sk = 32);
Impl.secret_to_public (C.ctypes_buf pk) (C.ctypes_buf sk)
let scalarmult ~scalar ~point ~result =
check_reqs Impl.reqs;
(* Hacl.Impl.Curve25519.Generic.scalarmult_st *)
assert (C.disjoint result scalar);
assert (C.disjoint result point);
assert (C.size result = 32);
assert (C.size scalar = 32);
assert (C.size point = 32);
Impl.scalarmult (C.ctypes_buf result) (C.ctypes_buf scalar) (C.ctypes_buf point)
let ecdh ~sk ~pk ~shared =
check_reqs Impl.reqs;
(* Hacl.Impl.Curve25519.Generic.ecdh_st *)
assert (C.disjoint shared sk);
assert (C.disjoint shared pk);
assert (C.size shared = 32);
assert (C.size sk = 32);
assert (C.size pk = 32);
Impl.ecdh (C.ctypes_buf shared) (C.ctypes_buf sk) (C.ctypes_buf pk)
end
let secret_to_public ~sk =
let pk = C.make 32 in
Noalloc.secret_to_public ~sk ~pk;
pk
let scalarmult ~scalar ~point =
let result = C.make 32 in
Noalloc.scalarmult ~scalar ~point ~result;
result
let ecdh ~sk ~pk =
let shared = C.make 32 in
if Noalloc.ecdh ~sk ~pk ~shared then
Some shared
else
None
end
module Make_EdDSA_generic (C: Buffer)
(Impl : sig
val secret_to_public : C.buf -> C.buf -> unit
val sign : C.buf -> C.buf -> uint32 -> C.buf -> unit
val verify : C.buf -> uint32 -> C.buf -> C.buf -> bool
val expand_keys : C.buf -> C.buf -> unit
val sign_expanded : C.buf -> C.buf -> uint32 -> C.buf -> unit
end)
= struct
type bytes = C.t
let max_size_t = pow2 32
let verify ~pk ~msg ~signature =
(* Hacl.Ed25519.verify *)
assert (C.size pk = 32);
assert (C.size signature = 64);
assert Z.(of_int (C.size msg) + ~$64 <= max_size_t);
Impl.verify (C.ctypes_buf pk) (C.size_uint32 msg) (C.ctypes_buf msg) (C.ctypes_buf signature)
module Noalloc = struct
let secret_to_public ~sk ~pk =
(* Hacl.Ed25519.secret_to_public *)
assert (C.size pk = 32);
assert (C.size sk = 32);
assert (C.disjoint pk sk);
Impl.secret_to_public (C.ctypes_buf pk) (C.ctypes_buf sk)
let sign ~sk ~msg ~signature =
(* Hacl.Ed25519.sign *)
assert (C.size sk = 32);
assert (C.size signature = 64);
assert Z.(of_int (C.size msg) + ~$64 <= max_size_t);
Impl.sign (C.ctypes_buf signature) (C.ctypes_buf sk) (C.size_uint32 msg) (C.ctypes_buf msg)
let expand_keys ~sk ~ks =
(* Hacl.Ed25519.expand_keys *)
assert (C.size ks = 96);
assert (C.size sk = 32);
assert (C.disjoint ks sk); (* VD: redundant for Bytes, since size is different *)
Impl.expand_keys (C.ctypes_buf ks) (C.ctypes_buf sk)
let sign_expanded ~ks ~msg ~signature =
(* Hacl.Ed25519.sign_expanded *)
assert (C.size ks = 96);
assert (C.size signature = 64);
assert Z.(of_int (C.size msg) + ~$64 <= max_size_t);
Impl.sign_expanded (C.ctypes_buf signature) (C.ctypes_buf ks) (C.size_uint32 msg) (C.ctypes_buf msg)
end
let secret_to_public ~sk =
let pk = C.make 32 in
Noalloc.secret_to_public ~sk ~pk;
pk
let sign ~sk ~msg =
let signature = C.make 64 in
Noalloc.sign ~sk ~msg ~signature;
signature
let expand_keys ~sk =
let ks = C.make 96 in
Noalloc.expand_keys ~sk ~ks;
ks
let sign_expanded ~ks ~msg =
let signature = C.make 64 in
Noalloc.sign_expanded ~ks ~msg ~signature;
signature
end
(* HashDefs only defines algorithms that are included in the EverCrypt agile hashing interface.
In addition to these, HACL* also includes SHA-3. We extend the `hash_alg` type so we can
use the same functor for all hash functions. *)
type all_hash_alg =
| Agile of HashDefs.alg
| SHA3_224
| SHA3_256
| SHA3_384
| SHA3_512
module Make_HashFunction_generic (C: Buffer)
(Impl : sig
val hash_alg : all_hash_alg
val hash : C.buf -> uint32 -> C.buf -> unit
end)
= struct
type bytes = C.t
let digest_len = function
| SHA3_224 -> 28
| SHA3_256 -> 32
| SHA3_384 -> 48
| SHA3_512 -> 64
| Agile alg -> HashDefs.digest_len alg
let check_max_input_len alg len =
match alg with
| Agile alg -> HashDefs.check_max_input_len alg len
| _ -> ()
module Noalloc = struct
let hash ~msg ~digest =
check_max_input_len Impl.hash_alg (C.size msg);
assert (C.size digest = digest_len Impl.hash_alg);
assert (C.disjoint msg digest);
Impl.hash (C.ctypes_buf msg) (C.size_uint32 msg) (C.ctypes_buf digest)
end
let hash msg =
let digest = C.make (digest_len Impl.hash_alg) in
Noalloc.hash ~msg ~digest;
digest
end
module Make_Poly1305_generic (C: Buffer)
(Impl : sig
val reqs : feature list
val mac : C.buf -> uint32 -> C.buf -> C.buf -> unit
end)
= struct
type bytes = C.t
module Noalloc = struct
let mac ~key ~msg ~tag =
check_reqs Impl.reqs;
(* Hacl.Impl.Poly1305.poly1305_mac_st *)
assert (C.size tag = 16);
assert (C.size key = 32);
assert (C.disjoint tag msg);
assert (C.disjoint key msg);
Impl.mac (C.ctypes_buf tag) (C.size_uint32 msg) (C.ctypes_buf msg) (C.ctypes_buf key)
end
let mac ~key ~msg =
let tag = C.make 16 in
Noalloc.mac ~key ~msg ~tag;
tag
end
module Make_HMAC_generic (C: Buffer)
(Impl : sig
val hash_alg : HashDefs.alg
val mac : C.buf -> C.buf -> uint32 -> C.buf -> uint32 -> unit
end)
= struct
type bytes = C.t
module Noalloc = struct
let mac ~key ~msg ~tag =
(* Hacl.HMAC.compute_st *)
assert (HashDefs.digest_len Impl.hash_alg = C.size tag);
assert (C.disjoint tag key);
HashDefs.check_key_len Impl.hash_alg (C.size key);
HashDefs.check_key_len Impl.hash_alg (C.size msg);
Impl.mac (C.ctypes_buf tag) (C.ctypes_buf key) (C.size_uint32 key) (C.ctypes_buf msg) (C.size_uint32 msg)
end
let mac ~key ~msg =
let tag = C.make (HashDefs.digest_len Impl.hash_alg) in
Noalloc.mac ~key ~msg ~tag;
tag
end
module Make_HKDF_generic (C: Buffer)
(Impl: sig
val hash_alg : HashDefs.alg
val extract : C.buf -> C.buf -> uint32 -> C.buf -> uint32 -> unit
val expand : C.buf -> C.buf -> uint32 -> C.buf -> uint32 -> uint32 -> unit
end)
= struct
type bytes = C.t
module Noalloc = struct
let extract ~salt ~ikm ~prk =
(* Hacl.HKDF.extract_st *)
assert (C.size prk = HashDefs.digest_len Impl.hash_alg);
assert (C.disjoint salt prk);
assert (C.disjoint ikm prk);
HashDefs.check_key_len Impl.hash_alg (C.size salt);
HashDefs.check_key_len Impl.hash_alg (C.size ikm);
Impl.extract (C.ctypes_buf prk) (C.ctypes_buf salt) (C.size_uint32 salt) (C.ctypes_buf ikm) (C.size_uint32 ikm)
let expand ~prk ~info ~okm =
(* Hacl.HKDF.expand_st *)
assert (C.size okm <= 255 * HashDefs.digest_len Impl.hash_alg);
assert (C.disjoint okm prk);
assert (HashDefs.digest_len Impl.hash_alg <= C.size prk);
HashDefs.(check_max_input_len Impl.hash_alg (digest_len Impl.hash_alg + block_len Impl.hash_alg + C.size info + 1));
HashDefs.check_key_len Impl.hash_alg (C.size prk);
Impl.expand (C.ctypes_buf okm) (C.ctypes_buf prk) (C.size_uint32 prk) (C.ctypes_buf info) (C.size_uint32 info) (C.size_uint32 okm)
end
let extract ~salt ~ikm =
let prk = C.make (HashDefs.digest_len Impl.hash_alg) in
Noalloc.extract ~salt ~ikm ~prk;
prk
let expand ~prk ~info ~size =
let okm = C.make size in
Noalloc.expand ~prk ~info ~okm;
okm
end
module Make_ECDSA_generic (C: Buffer)
(Impl : sig
val min_msg_size : int
val sign : C.buf -> uint32 -> C.buf -> C.buf -> C.buf -> bool
val verify : uint32 -> C.buf -> C.buf -> C.buf -> C.buf -> bool
end)
= struct
type bytes = C.t
let get_result r =
if r = UInt64.zero then
true
else
if r = UInt64.max_int then
false
else
failwith "Unknown return value"
let prime_p256_order = Z.of_string "115792089210356248762697446949407573529996955224135760342422259061068512044369"
module Noalloc = struct
let sign ~sk ~msg ~k ~signature =
(* Hacl.Interface.P256.ECDSA.ecdsa_sign_p256_without_hash/sha2/sha384 *)
assert (C.size signature = 64);
assert (C.size sk = 32);
assert (C.size k = 32);
assert (C.size msg >= Impl.min_msg_size);
assert (C.disjoint signature msg);
assert (C.z_compare sk prime_p256_order < 0);
assert (C.z_compare k prime_p256_order < 0);
Impl.sign (C.ctypes_buf signature) (C.size_uint32 msg) (C.ctypes_buf msg) (C.ctypes_buf sk) (C.ctypes_buf k)
end
let sign ~sk ~msg ~k =
let signature = C.make 64 in
if Noalloc.sign ~sk ~msg ~k ~signature then
Some signature
else
None
let verify ~pk ~msg ~signature =
(* Hacl.Interface.P256.ECDSA.ecdsa_verif_without_hash/sha2/sha384 *)
assert (C.size signature = 64);
assert (C.size pk = 64);
assert (C.size msg >= Impl.min_msg_size);
let r, s = C.sub signature 0 32, C.sub signature 32 32 in
Impl.verify (C.size_uint32 msg) (C.ctypes_buf msg) (C.ctypes_buf pk) (C.ctypes_buf r) (C.ctypes_buf s)
end
module Make_Blake2b_generic (C: Buffer)
(Impl : sig
val reqs : feature list
val blake2b : uint32 -> C.buf -> uint32 -> C.buf -> uint32 -> C.buf -> unit
end)
= struct
type bytes = C.t
module Noalloc = struct
let hash ~key ~msg ~digest =
check_reqs Impl.reqs;
(* specs/Spec.Blake2.blake2b *)
assert (C.size digest > 0 && C.size digest <= 64);
assert (C.size key <= 64);
if C.size key = 0 then
assert Z.(of_int (C.size msg) < pow2 128)
else
assert Z.(of_int (C.size msg) + ~$128 < pow2 128);
assert (C.disjoint key msg);
assert (C.disjoint key digest);
assert (C.disjoint msg digest);
Impl.blake2b (C.size_uint32 digest) (C.ctypes_buf digest) (C.size_uint32 msg) (C.ctypes_buf msg) (C.size_uint32 key) (C.ctypes_buf key)
end
let hash ?(key = C.empty) msg size =
assert (size > 0 && size <= 64);
let digest = C.make size in
Noalloc.hash ~key ~msg ~digest;
digest
end
module Make_Blake2s_generic (C: Buffer)
(Impl : sig
val reqs : feature list
val blake2s : uint32 -> C.buf -> uint32 -> C.buf -> uint32 -> C.buf -> unit
end)
= struct
type bytes = C.t
module Noalloc = struct
let hash ~key ~msg ~digest =
check_reqs Impl.reqs;
(* specs/Spec.Blake2.blake2s *)
assert (C.size digest > 0 && C.size digest <= 32);
assert (C.size key <= 32);
if C.size key = 0 then
assert Z.(of_int (C.size msg) < pow2 64)
else
assert Z.(of_int (C.size msg) + ~$64 < pow2 64);
assert (C.disjoint key msg);
assert (C.disjoint key digest);
assert (C.disjoint msg digest);
Impl.blake2s (C.size_uint32 digest) (C.ctypes_buf digest) (C.size_uint32 msg) (C.ctypes_buf msg) (C.size_uint32 key) (C.ctypes_buf key)
end
let hash ?(key = C.empty) msg size =
assert (size > 0 && size <= 32);
let digest = C.make size in
Noalloc.hash ~key ~msg ~digest;
digest
end
module Make_Chacha20_Poly1305 = Make_Chacha20_Poly1305_generic (CBytes)
module Make_Curve25519 = Make_Curve25519_generic (CBytes)
module Make_EdDSA = Make_EdDSA_generic (CBytes)
module Make_HashFunction = Make_HashFunction_generic (CBytes)
module Make_Poly1305 = Make_Poly1305_generic (CBytes)
module Make_HMAC = Make_HMAC_generic (CBytes)
module Make_HKDF = Make_HKDF_generic (CBytes)
module Make_ECDSA = Make_ECDSA_generic (CBytes)
module Make_Blake2b = Make_Blake2b_generic (CBytes)
module Make_Blake2s = Make_Blake2s_generic (CBytes)