forked from emillon/hacl-star-dune
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathEverCrypt.ml
311 lines (284 loc) · 11.3 KB
/
EverCrypt.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
open Ctypes
open Unsigned
open SharedDefs
open SharedFunctors
module C = CBytes
type bytes = CBytes.t
module Hacl_Spec = Hacl_Spec_bindings.Bindings(Hacl_Spec_stubs)
module EverCrypt_AEAD = EverCrypt_AEAD_bindings.Bindings(EverCrypt_AEAD_stubs)
module EverCrypt_Chacha20Poly1305 = EverCrypt_Chacha20Poly1305_bindings.Bindings(EverCrypt_Chacha20Poly1305_stubs)
module EverCrypt_Curve25519 = EverCrypt_Curve25519_bindings.Bindings(EverCrypt_Curve25519_stubs)
module EverCrypt_Hash = EverCrypt_Hash_bindings.Bindings(EverCrypt_Hash_stubs)
module EverCrypt_HMAC = EverCrypt_HMAC_bindings.Bindings(EverCrypt_HMAC_stubs)
module EverCrypt_Poly1305 = EverCrypt_Poly1305_bindings.Bindings(EverCrypt_Poly1305_stubs)
module EverCrypt_HKDF = EverCrypt_HKDF_bindings.Bindings(EverCrypt_HKDF_stubs)
module EverCrypt_DRBG = EverCrypt_DRBG_bindings.Bindings(EverCrypt_DRBG_stubs)
module EverCrypt_Ed25519 = EverCrypt_Ed25519_bindings.Bindings(EverCrypt_Ed25519_stubs)
module Error = struct
type error_code =
| UnsupportedAlgorithm
| InvalidKey
| AuthenticationFailure
| InvalidIVLength
| DecodeError
type 'a result =
| Success of 'a
| Error of error_code
let error n =
let err = match n with
| 1 -> UnsupportedAlgorithm
| 2 -> InvalidKey
| 3 -> AuthenticationFailure
| 4 -> InvalidIVLength
| 5 -> DecodeError
| _ -> failwith "Impossible"
in
Error err
let get_result r = match UInt8.to_int r with
| 0 -> Success ()
| n -> error n
end
let at_exit_full_major = lazy (at_exit Gc.full_major)
module AEAD = struct
open Error
open SharedDefs.AEADDefs
open EverCrypt_AEAD
type t = alg * (everCrypt_AEAD_state_s ptr) ptr
let init ~alg ~key : t result =
Lazy.force at_exit_full_major;
assert (C.size key = key_length alg);
let st = allocate
~finalise:(fun st -> everCrypt_AEAD_free (!@ st))
(ptr everCrypt_AEAD_state_s)
(from_voidp everCrypt_AEAD_state_s null)
in
match UInt8.to_int (everCrypt_AEAD_create_in (alg_definition alg) st (C.ctypes_buf key)) with
| 0 -> Success (alg, st)
| n -> error n
module Noalloc = struct
let encrypt ~st:(alg, st) ~iv ~ad ~pt ~ct ~tag : unit result =
(* providers/EverCrypt.AEAD.encrypt_pre *)
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 ct tag);
assert (C.disjoint iv ct);
assert (C.disjoint iv tag);
assert (C.disjoint pt tag);
assert (C.disjoint pt ad);
assert (C.disjoint ad ct);
assert (C.disjoint ad tag);
get_result (everCrypt_AEAD_encrypt (!@st)
(C.ctypes_buf iv) (C.size_uint32 iv) (C.ctypes_buf ad) (C.size_uint32 ad)
(C.ctypes_buf pt) (C.size_uint32 pt) (C.ctypes_buf ct) (C.ctypes_buf tag))
let decrypt ~st:(alg, st) ~iv ~ad ~ct ~tag ~pt : unit result =
(* EverCrypt.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);
assert (C.disjoint tag pt);
assert (C.disjoint tag ct);
assert (C.disjoint tag ad);
assert (C.disjoint ct ad);
assert (C.disjoint pt ad);
get_result (everCrypt_AEAD_decrypt (!@st)
(C.ctypes_buf iv) (C.size_uint32 iv) (C.ctypes_buf ad) (C.size_uint32 ad)
(C.ctypes_buf ct) (C.size_uint32 ct) (C.ctypes_buf tag) (C.ctypes_buf pt))
end
let encrypt ~st:(alg, st) ~iv ~ad ~pt =
let ct = C.make (C.size pt) in
let tag = C.make (tag_length alg) in
match Noalloc.encrypt ~st:(alg, st) ~iv ~ad ~pt ~ct ~tag with
| Success () -> Success (ct, tag)
| Error n -> Error n
let decrypt ~st:(alg, st) ~iv ~ad ~ct ~tag =
let pt = C.make (C.size ct) in
match Noalloc.decrypt ~st:(alg, st) ~iv ~ad ~ct ~tag ~pt with
| Success () -> Success pt
| Error n -> Error n
end
module Chacha20_Poly1305 : Chacha20_Poly1305 =
Make_Chacha20_Poly1305 (struct
(* EverCrypt already performs these runtime checks so all `reqs` attributes in
* this file are empty since there is no need to do them here. *)
let reqs = []
let encrypt = EverCrypt_Chacha20Poly1305.everCrypt_Chacha20Poly1305_aead_encrypt
let decrypt = EverCrypt_Chacha20Poly1305.everCrypt_Chacha20Poly1305_aead_decrypt
end)
module Curve25519 : Curve25519 =
Make_Curve25519 (struct
let reqs = []
let secret_to_public = EverCrypt_Curve25519.everCrypt_Curve25519_secret_to_public
let scalarmult = EverCrypt_Curve25519.everCrypt_Curve25519_scalarmult
let ecdh = EverCrypt_Curve25519.everCrypt_Curve25519_ecdh
end)
module Ed25519 : EdDSA =
Make_EdDSA (struct
let secret_to_public = EverCrypt_Ed25519.everCrypt_Ed25519_secret_to_public
let sign = EverCrypt_Ed25519.everCrypt_Ed25519_sign
let verify = EverCrypt_Ed25519.everCrypt_Ed25519_verify
let expand_keys = EverCrypt_Ed25519.everCrypt_Ed25519_expand_keys
let sign_expanded = EverCrypt_Ed25519.everCrypt_Ed25519_sign_expanded
end)
module Hash = struct
open HashDefs
open EverCrypt_Hash
module Noalloc = struct
let hash ~alg ~msg ~digest =
check_max_input_len alg (C.size msg);
assert (C.size digest = digest_len alg);
assert (C.disjoint digest msg);
everCrypt_Hash_hash (alg_definition alg) (C.ctypes_buf digest) (C.ctypes_buf msg) (C.size_uint32 msg)
let finish ~st:(alg, _, t) ~digest =
assert (C.size digest = digest_len alg);
everCrypt_Hash_Incremental_finish t (C.ctypes_buf digest)
end
type t = alg * Z.t ref * hacl_Streaming_Functor_state_s___EverCrypt_Hash_state_s____ ptr
let init ~alg =
Lazy.force at_exit_full_major;
let alg_spec = alg_definition alg in
let st = everCrypt_Hash_Incremental_create_in alg_spec in
everCrypt_Hash_Incremental_init st;
let incr_len = ref Z.zero in
Gc.finalise everCrypt_Hash_Incremental_free st;
(alg, incr_len, st)
let update ~st:(alg, incr_len, t) ~msg =
check_max_input_len alg (C.size msg);
incr_len := Z.add !incr_len (Z.of_int (C.size msg));
assert (Z.lt !incr_len (max_input_len alg));
everCrypt_Hash_Incremental_update t (C.ctypes_buf msg) (C.size_uint32 msg)
let finish ~st:(alg, incr_len, t) =
let digest = C.make (digest_len alg) in
Noalloc.finish ~st:(alg, incr_len, t) ~digest;
digest
let hash ~alg ~msg =
let digest = C.make (digest_len alg) in
Noalloc.hash ~alg ~msg ~digest;
digest
end
module SHA2_224 : HashFunction =
Make_HashFunction (struct
let hash_alg = Agile HashDefs.SHA2_224
let hash = EverCrypt_Hash.everCrypt_Hash_hash_224
end)
module SHA2_256 : HashFunction =
Make_HashFunction (struct
let hash_alg = Agile HashDefs.SHA2_256
let hash = EverCrypt_Hash.everCrypt_Hash_hash_256
end)
module HMAC = struct
open EverCrypt_HMAC
let is_supported_alg ~alg =
everCrypt_HMAC_is_supported_alg (HashDefs.alg_definition alg)
module Noalloc = struct
let mac ~alg ~key ~msg ~tag=
(* Hacl.HMAC.compute_st *)
assert (C.size tag = HashDefs.digest_len alg);
assert (C.disjoint msg tag);
HashDefs.check_key_len alg (C.size key);
HashDefs.check_key_len alg (C.size msg);
everCrypt_HMAC_compute (HashDefs.alg_definition alg) (C.ctypes_buf tag) (C.ctypes_buf key) (C.size_uint32 key) (C.ctypes_buf msg) (C.size_uint32 msg)
end
let mac ~alg ~key ~msg =
let tag = C.make (HashDefs.digest_len alg) in
Noalloc.mac ~alg ~key ~msg ~tag;
tag
end
module HMAC_SHA2_256 : MAC =
Make_HMAC (struct
let hash_alg = HashDefs.SHA2_256
let mac = EverCrypt_HMAC.everCrypt_HMAC_compute_sha2_256
end)
module HMAC_SHA2_384 : MAC =
Make_HMAC (struct
let hash_alg = HashDefs.SHA2_384
let mac = EverCrypt_HMAC.everCrypt_HMAC_compute_sha2_384
end)
module HMAC_SHA2_512 : MAC =
Make_HMAC (struct
let hash_alg = HashDefs.SHA2_512
let mac = EverCrypt_HMAC.everCrypt_HMAC_compute_sha2_512
end)
module Poly1305 : MAC =
Make_Poly1305 (struct
let reqs = []
let mac dst data_len data key = EverCrypt_Poly1305.everCrypt_Poly1305_poly1305 dst data data_len key
end)
module HKDF = struct
open EverCrypt_HKDF
module Noalloc = struct
let extract ~alg ~salt ~ikm ~prk =
(* Hacl.HKDF.extract_st *)
assert (C.size prk = HashDefs.digest_len alg);
assert (C.disjoint salt prk);
assert (C.disjoint ikm prk);
HashDefs.check_key_len alg (C.size salt);
HashDefs.check_key_len alg (C.size ikm);
everCrypt_HKDF_extract (HashDefs.alg_definition alg) (C.ctypes_buf prk) (C.ctypes_buf salt) (C.size_uint32 salt) (C.ctypes_buf ikm) (C.size_uint32 ikm)
let expand ~alg ~prk ~info ~okm =
(* Hacl.HKDF.expand_st *)
assert (C.size okm <= 255 * HashDefs.digest_len alg);
assert (C.disjoint okm prk);
assert (HashDefs.digest_len alg <= C.size prk);
HashDefs.(check_max_input_len alg (digest_len alg + block_len alg + C.size info + 1));
HashDefs.check_key_len alg (C.size prk);
everCrypt_HKDF_expand (HashDefs.alg_definition alg) (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 ~alg ~salt ~ikm =
let prk = C.make (HashDefs.digest_len alg) in
Noalloc.extract ~alg ~salt ~ikm ~prk;
prk
let expand ~alg ~prk ~info ~size =
let okm = C.make size in
Noalloc.expand ~alg ~prk ~info ~okm;
okm
end
module HKDF_SHA2_256 : HKDF =
Make_HKDF (struct
let hash_alg = HashDefs.SHA2_256
let expand = EverCrypt_HKDF.everCrypt_HKDF_expand_sha2_256
let extract = EverCrypt_HKDF.everCrypt_HKDF_extract_sha2_256
end)
module HKDF_SHA2_384 : HKDF =
Make_HKDF (struct
let hash_alg = HashDefs.SHA2_384
let expand = EverCrypt_HKDF.everCrypt_HKDF_expand_sha2_384
let extract = EverCrypt_HKDF.everCrypt_HKDF_extract_sha2_384
end)
module HKDF_SHA2_512 : HKDF =
Make_HKDF (struct
let hash_alg = HashDefs.SHA2_512
let expand = EverCrypt_HKDF.everCrypt_HKDF_expand_sha2_512
let extract = EverCrypt_HKDF.everCrypt_HKDF_extract_sha2_512
end)
module DRBG = struct
open EverCrypt_DRBG
type t = everCrypt_DRBG_state_s ptr
module Noalloc = struct
let generate ?(additional_input=Bytes.empty) st output =
(* EverCrypt.DRBG.generate_st *)
assert (C.disjoint output additional_input);
everCrypt_DRBG_generate (C.ctypes_buf output) st (C.size_uint32 output) (C.ctypes_buf additional_input) (C.size_uint32 additional_input)
end
let is_supported_alg alg =
(* as defined in Spec.HMAC_DRBG, excluding SHA-1 *)
alg = HashDefs.SHA2_256 || alg = HashDefs.SHA2_384 || alg = HashDefs.SHA2_512
let instantiate ?(personalization_string=Bytes.empty) alg =
(* EverCrypt.DRBG.instantiate_st *)
if is_supported_alg alg then
let st = everCrypt_DRBG_create (HashDefs.alg_definition alg) in
if everCrypt_DRBG_instantiate st (C.ctypes_buf personalization_string) (C.size_uint32 personalization_string) then begin
Gc.finalise everCrypt_DRBG_uninstantiate st;
Some st
end else
None
else
None
let generate ?(additional_input=Bytes.empty) st size =
let output = C.make size in
if Noalloc.generate ~additional_input st output then
Some output
else
None
let reseed ?(additional_input=Bytes.empty) st =
(* EverCrypt.DRBG.reseed_st *)
everCrypt_DRBG_reseed st (C.ctypes_buf additional_input) (C.size_uint32 additional_input)
end