forked from
gazagnaire.org/ocaml-crypto
upstream: https://github.com/mirage/mirage-crypto
1(** Simpler crypto
2
3 Mirage-crypto is a cryptographic library.
4
5 The overarching API principle is simply mapping inputs to outputs, wherever
6 feasible.
7
8 Similar algorithms in the same class (like {{!Hash}hashes} or
9 {{!Cipher_block}block ciphers}) are presented as distinct modules sharing
10 the same signature.
11
12 The opam package mirage-crypto-rng provides a cryptographically secure
13 pseudo-random number generator, the package mirage-crypto-pk provides public
14 key cryptography. *)
15
16(**/**)
17
18(** A treasure-trove of random utilities.
19
20 This is largely an internal API used in related sub-libraries or tests. As
21 such, it is prone to breakage. *)
22module Uncommon : sig
23 val ( // ) : int -> int -> int
24 (** [x // y] is the ceiling division [ceil (x / y)].
25
26 [x // y] is [0] for any non-positive [x].
27
28 @raise Division_by_zero when [y < 1]. *)
29
30 val imin : int -> int -> int
31 val imax : int -> int -> int
32 val iter2 : 'a -> 'a -> ('a -> unit) -> unit
33 val iter3 : 'a -> 'a -> 'a -> ('a -> unit) -> unit
34 val xor : string -> string -> string
35
36 val unsafe_xor_into :
37 string -> src_off:int -> bytes -> dst_off:int -> int -> unit
38
39 val invalid_arg : ('a, Format.formatter, unit, unit, unit, 'b) format6 -> 'a
40end
41
42(**/**)
43
44(** The poly1305 message authentication code *)
45module Poly1305 : sig
46 type 'a iter = ('a -> unit) -> unit
47
48 type t
49 (** Represents a running mac computation, suitable for appending inputs. *)
50
51 val mac_size : int
52 (** [mac_size] is the size of the output. *)
53
54 val empty : key:string -> t
55 (** [empty] is the empty context with the given [key].
56
57 @raise Invalid_argument if key is not 32 bytes. *)
58
59 val feed : t -> string -> t
60 (** [feed t msg] adds the information in [msg] to [t]. *)
61
62 val feedi : t -> string iter -> t
63 (** [feedi t iter] feeds iter into [t]. *)
64
65 val get : t -> string
66 (** [get t] is the mac corresponding to [t]. *)
67
68 val mac : key:string -> string -> string
69 (** [mac ~key msg] is the all-in-one mac computation:
70 [get (feed (empty ~key) msg)]. *)
71
72 val maci : key:string -> string iter -> string
73 (** [maci ~key iter] is the all-in-one mac computation:
74 [get (feedi (empty ~key) iter)]. *)
75
76 val mac_into :
77 key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
78 (** [mac_into ~key datas dst dst_off] computes the [mac] of [datas]. *)
79
80 (**/**)
81
82 val unsafe_mac_into :
83 key:string -> (string * int * int) list -> bytes -> dst_off:int -> unit
84 (** [unsafe_mac_into ~key datas dst dst_off] is {!mac_into} without bounds
85 checks. *)
86
87 (**/**)
88end
89
90(** {1 Symmetric-key cryptography} *)
91
92(** Authenticated encryption with associated data.
93
94 This defines a uniform interface of symmetrics cryptographic algorithms
95 which encrypt, and also protect the integrity of the data. Additional data,
96 only used for integrity protection, not encrypted and not part of the
97 ciphertext, can be passed in optionally. This prevents the same ciphertext
98 being used at a different location. See
99 {{:https://tools.ietf.org/html/rfc5116}RFC 5116} for further description. *)
100module type AEAD = sig
101 val tag_size : int
102 (** The size of the authentication tag. *)
103
104 type key
105 (** The abstract type for the key. *)
106
107 val of_secret : string -> key
108 (** [of_secret secret] constructs the encryption key corresponding to
109 [secret].
110
111 @raise Invalid_argument if the length of [secret] is not a valid key size.
112 *)
113
114 (** {1 Authenticated encryption and decryption with inline tag} *)
115
116 val authenticate_encrypt :
117 key:key -> nonce:string -> ?adata:string -> string -> string
118 (** [authenticate_encrypt ~key ~nonce ~adata msg] encrypts [msg] with [key]
119 and [nonce], and appends an authentication tag computed over the encrypted
120 [msg], using [key], [nonce], and [adata].
121
122 @raise Invalid_argument if [nonce] is not of the right size. *)
123
124 val authenticate_decrypt :
125 key:key -> nonce:string -> ?adata:string -> string -> string option
126 (** [authenticate_decrypt ~key ~nonce ~adata msg] splits [msg] into encrypted
127 data and authentication tag, computes the authentication tag using [key],
128 [nonce], and [adata], and decrypts the encrypted data. If the
129 authentication tags match, the decrypted data is returned.
130
131 @raise Invalid_argument if [nonce] is not of the right size. *)
132
133 (** {1 Authenticated encryption and decryption with tag provided separately}
134 *)
135
136 val authenticate_encrypt_tag :
137 key:key -> nonce:string -> ?adata:string -> string -> string * string
138 (** [authenticate_encrypt_tag ~key ~nonce ~adata msg] encrypts [msg] with
139 [key] and [nonce]. The computed authentication tag is returned separately
140 as second part of the tuple.
141
142 @raise Invalid_argument if [nonce] is not of the right size. *)
143
144 val authenticate_decrypt_tag :
145 key:key ->
146 nonce:string ->
147 ?adata:string ->
148 tag:string ->
149 string ->
150 string option
151 (** [authenticate_decrypt ~key ~nonce ~adata ~tag msg] computes the
152 authentication tag using [key], [nonce], and [adata], and decrypts the
153 encrypted data. If the authentication tags match, the decrypted data is
154 returned.
155
156 @raise Invalid_argument if [nonce] is not of the right size. *)
157
158 (** {1 Authenticated encryption and decryption into existing buffers} *)
159
160 val authenticate_encrypt_into :
161 key:key ->
162 nonce:string ->
163 ?adata:string ->
164 string ->
165 src_off:int ->
166 bytes ->
167 dst_off:int ->
168 tag_off:int ->
169 int ->
170 unit
171 (** [authenticate_encrypt_into ~key ~nonce ~adata msg ~src_off dst ~dst_off
172 ~tag_off len] encrypts [len] bytes of [msg] starting at [src_off] with
173 [key] and [nonce]. The output is put into [dst] at [dst_off], the tag into
174 [dst] at [tag_off].
175
176 @raise Invalid_argument if [nonce] is not of the right size.
177 @raise Invalid_argument if [String.length msg - src_off < len].
178 @raise Invalid_argument if [Bytes.length dst - dst_off < len].
179 @raise Invalid_argument if [Bytes.length dst - tag_off < tag_size]. *)
180
181 val authenticate_decrypt_into :
182 key:key ->
183 nonce:string ->
184 ?adata:string ->
185 string ->
186 src_off:int ->
187 tag_off:int ->
188 bytes ->
189 dst_off:int ->
190 int ->
191 bool
192 (** [authenticate_decrypt_into ~key ~nonce ~adata msg ~src_off ~tag_off dst
193 ~dst_off len] computes the authentication tag using [key], [nonce], and
194 [adata], and decrypts the [len] bytes encrypted data from [msg] starting
195 at [src_off] into [dst] starting at [dst_off]. If the authentication tags
196 match, [true] is returned, and the decrypted data is in [dst].
197
198 @raise Invalid_argument if [nonce] is not of the right size.
199 @raise Invalid_argument if [String.length msg - src_off < len].
200 @raise Invalid_argument if [Bytes.length dst - dst_off < len].
201 @raise Invalid_argument if [String.length msg - tag_off < tag_size]. *)
202
203 (**/**)
204
205 val unsafe_authenticate_encrypt_into :
206 key:key ->
207 nonce:string ->
208 ?adata:string ->
209 string ->
210 src_off:int ->
211 bytes ->
212 dst_off:int ->
213 tag_off:int ->
214 int ->
215 unit
216 (** [unsafe_authenticate_encrypt_into] is {!authenticate_encrypt_into}, but
217 without bounds checks.
218
219 @raise Invalid_argument if [nonce] is not of the right size.
220
221 This may cause memory issues if an invariant is violated:
222 - [String.length msg - src_off >= len].
223 - [Bytes.length dst - dst_off >= len].
224 - [Bytes.length dst - tag_off >= tag_size]. *)
225
226 val unsafe_authenticate_decrypt_into :
227 key:key ->
228 nonce:string ->
229 ?adata:string ->
230 string ->
231 src_off:int ->
232 tag_off:int ->
233 bytes ->
234 dst_off:int ->
235 int ->
236 bool
237 (** [unsafe_authenticate_decrypt_into] is {!authenticate_decrypt_into}, but
238 without bounds checks.
239
240 @raise Invalid_argument if [nonce] is not of the right size.
241
242 This may cause memory issues if an invariant is violated:
243 - [String.length msg - src_off >= len].
244 - [Bytes.length dst - dst_off >= len].
245 - [String.length msg - tag_off >= tag_size]. *)
246
247 (**/**)
248end
249
250(** Block ciphers.
251
252 Each algorithm, and each mode of operation, is contained in its own separate
253 module. *)
254
255(** Module types for various block cipher modes of operation. *)
256module Block : sig
257 (** Modes of operation: *)
258
259 (** {e Electronic Codebook} "mode". *)
260 module type ECB = sig
261 type key
262
263 val of_secret : string -> key
264 (** Construct the encryption key corresponding to [secret].
265
266 @raise Invalid_argument
267 if the length of [secret] is not in {{!key_sizes}[key_sizes]}. *)
268
269 val key_sizes : int array
270 (** Key sizes allowed with this cipher. *)
271
272 val block_size : int
273 (** The size of a single block. *)
274
275 val encrypt : key:key -> string -> string
276 (** [encrypt ~key src] encrypts [src] into a freshly allocated buffer of the
277 same size using [key].
278
279 @raise Invalid_argument
280 if the length of [src] is not a multiple of {!block_size}. *)
281
282 val decrypt : key:key -> string -> string
283 (** [decrypt ~key src] decrypts [src] into a freshly allocated buffer of the
284 same size using [key].
285
286 @raise Invalid_argument
287 if the length of [src] is not a multiple of {!block_size}. *)
288
289 val encrypt_into :
290 key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
291 (** [encrypt_into ~key src ~src_off dst dst_off len] encrypts [len] octets
292 from [src] starting at [src_off] into [dst] starting at [dst_off].
293
294 @raise Invalid_argument if [len] is not a multiple of {!block_size}.
295 @raise Invalid_argument
296 if [src_off < 0 || String.length src - src_off < len].
297 @raise Invalid_argument
298 if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
299
300 val decrypt_into :
301 key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
302 (** [decrypt_into ~key src ~src_off dst dst_off len] decrypts [len] octets
303 from [src] starting at [src_off] into [dst] starting at [dst_off].
304
305 @raise Invalid_argument if [len] is not a multiple of {!block_size}.
306 @raise Invalid_argument
307 if [src_off < 0 || String.length src - src_off < len].
308 @raise Invalid_argument
309 if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
310
311 (**/**)
312
313 val unsafe_encrypt_into :
314 key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
315 (** [unsafe_encrypt_into] is {!encrypt_into}, but without bounds checks.
316
317 This may cause memory issues if an invariant is violated:
318 - [len] must be a multiple of {!block_size},
319 - [src_off >= 0 && String.length src - src_off >= len],
320 - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
321
322 val unsafe_decrypt_into :
323 key:key -> string -> src_off:int -> bytes -> dst_off:int -> int -> unit
324 (** [unsafe_decrypt_into] is {!decrypt_into}, but without bounds checks.
325
326 This may cause memory issues if an invariant is violated:
327 - [len] must be a multiple of {!block_size},
328 - [src_off >= 0 && String.length src - src_off >= len],
329 - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
330
331 (**/**)
332 end
333
334 (** {e Cipher-block chaining} mode. *)
335 module type CBC = sig
336 type key
337
338 val of_secret : string -> key
339 (** Construct the encryption key corresponding to [secret].
340
341 @raise Invalid_argument
342 if the length of [secret] is not in {{!key_sizes}[key_sizes]}. *)
343
344 val key_sizes : int array
345 (** Key sizes allowed with this cipher. *)
346
347 val block_size : int
348 (** The size of a single block. *)
349
350 val encrypt : key:key -> iv:string -> string -> string
351 (** [encrypt ~key ~iv msg] is [msg] encrypted under [key], using [iv] as the
352 CBC initialization vector.
353
354 @raise Invalid_argument
355 if [iv] is not [block_size], or [msg] is not [k * block_size] long. *)
356
357 val decrypt : key:key -> iv:string -> string -> string
358 (** [decrypt ~key ~iv msg] is the inverse of [encrypt].
359
360 @raise Invalid_argument
361 if [iv] is not [block_size], or [msg] is not [k * block_size] long. *)
362
363 val next_iv : ?off:int -> string -> iv:string -> string
364 (** [next_iv ~iv ciphertext ~off] is the first [iv] {e following} the
365 encryption that used [iv] to produce [ciphertext].
366
367 For protocols which perform inter-message chaining, this is the [iv] for
368 the next message.
369
370 It is either [iv], when [String.length ciphertext - off = 0], or the
371 last block of [ciphertext]. Note that
372
373 {[
374 encrypt ~iv msg1
375 || encrypt ~iv:(next_iv ~iv (encrypt ~iv msg1)) msg2
376 == encrypt ~iv (msg1 || msg2)
377 ]}
378
379 @raise Invalid_argument if the length of [iv] is not [block_size].
380 @raise Invalid_argument
381 if the length of [ciphertext] is not a multiple of [block_size]. *)
382
383 val encrypt_into :
384 key:key ->
385 iv:string ->
386 string ->
387 src_off:int ->
388 bytes ->
389 dst_off:int ->
390 int ->
391 unit
392 (** [encrypt_into ~key ~iv src ~src_off dst dst_off len] encrypts [len]
393 octets from [src] starting at [src_off] into [dst] starting at
394 [dst_off].
395
396 @raise Invalid_argument if the length of [iv] is not {!block_size}.
397 @raise Invalid_argument if [len] is not a multiple of {!block_size}.
398 @raise Invalid_argument
399 if [src_off < 0 || String.length src - src_off < len].
400 @raise Invalid_argument
401 if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
402
403 val decrypt_into :
404 key:key ->
405 iv:string ->
406 string ->
407 src_off:int ->
408 bytes ->
409 dst_off:int ->
410 int ->
411 unit
412 (** [decrypt_into ~key ~iv src ~src_off dst dst_off len] decrypts [len]
413 octets from [src] starting at [src_off] into [dst] starting at
414 [dst_off].
415
416 @raise Invalid_argument if the length of [iv] is not {!block_size}.
417 @raise Invalid_argument if [len] is not a multiple of {!block_size}.
418 @raise Invalid_argument
419 if [src_off < 0 || String.length src - src_off < len].
420 @raise Invalid_argument
421 if [dst_off < 0 || Bytes.length dst - dst_off < len]. *)
422
423 (**/**)
424
425 val unsafe_encrypt_into :
426 key:key ->
427 iv:string ->
428 string ->
429 src_off:int ->
430 bytes ->
431 dst_off:int ->
432 int ->
433 unit
434 (** [unsafe_encrypt_into] is {!encrypt_into}, but without bounds checks.
435
436 This may casue memory issues if an invariant is violated:
437 - the length of [iv] must be {!block_size},
438 - [len] must be a multiple of {!block_size},
439 - [src_off >= 0 && String.length src - src_off >= len],
440 - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
441
442 val unsafe_decrypt_into :
443 key:key ->
444 iv:string ->
445 string ->
446 src_off:int ->
447 bytes ->
448 dst_off:int ->
449 int ->
450 unit
451 (** [unsafe_decrypt_into] is {!decrypt_into}, but without bounds checks.
452
453 This may casue memory issues if an invariant is violated:
454 - the length of [iv] must be {!block_size},
455 - [len] must be a multiple of {!block_size},
456 - [src_off >= 0 && String.length src - src_off >= len],
457 - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
458
459 val unsafe_encrypt_into_inplace :
460 key:key -> iv:string -> bytes -> dst_off:int -> int -> unit
461 (** [unsafe_encrypt_into_inplace] is {!unsafe_encrypt_into}, but assumes
462 that [dst] already contains the mesage to be encrypted.
463
464 This may casue memory issues if an invariant is violated:
465 - the length of [iv] must be {!block_size},
466 - [len] must be a multiple of {!block_size},
467 - [src_off >= 0 && String.length src - src_off >= len],
468 - [dst_off >= 0 && Bytes.length dst - dst_off >= len]. *)
469
470 (**/**)
471 end
472
473 (** {e Counter} mode. *)
474 module type CTR = sig
475 type key
476
477 val of_secret : string -> key
478 (** Construct the encryption key corresponding to [secret].
479
480 @raise Invalid_argument
481 if the length of [secret] is not in {{!key_sizes}[key_sizes]}. *)
482
483 val key_sizes : int array
484 (** Key sizes allowed with this cipher. *)
485
486 val block_size : int
487 (** The size of a single block. *)
488
489 type ctr
490
491 val add_ctr : ctr -> int64 -> ctr
492 (** [add_ctr ctr n] adds [n] to [ctr]. *)
493
494 val next_ctr : ?off:int -> string -> ctr:ctr -> ctr
495 (** [next_ctr ~off msg ~ctr] is the state of the counter after encrypting or
496 decrypting [msg] at offset [off] with the counter [ctr].
497
498 For protocols which perform inter-message chaining, this is the counter
499 for the next message.
500
501 It is computed as [C.add ctr (ceil (len msg / block_size))]. Note that
502 if [len msg1 = k * block_size],
503
504 {[
505 encrypt ~ctr msg1
506 || encrypt ~ctr:(next_ctr ~ctr msg1) msg2
507 == encrypt ~ctr (msg1 || msg2)
508 ]} *)
509
510 val ctr_of_octets : string -> ctr
511 (** [ctr_of_octets buf] converts the value of [buf] into a counter. *)
512
513 val stream : key:key -> ctr:ctr -> int -> string
514 (** [stream ~key ~ctr n] is the raw keystream.
515
516 Keystream is the concatenation of successive encrypted counter states.
517 If [E(x)] is the single block [x] encrypted under [key], then keystream
518 is the first [n] bytes of
519 [E(ctr) || E(add ctr 1) || E(add ctr 2) || ...].
520
521 Note that
522
523 {[
524 stream ~key ~ctr (k * block_size)
525 || stream ~key ~ctr:(add ctr k) x
526 == stream ~key ~ctr ((k * block_size) + x)
527 ]}
528
529 In other words, it is possible to restart a keystream at [block_size]
530 boundaries by manipulating the counter. *)
531
532 val encrypt : key:key -> ctr:ctr -> string -> string
533 (** [encrypt ~key ~ctr msg] is [stream ~key ~ctr (len msg) lxor msg]. *)
534
535 val decrypt : key:key -> ctr:ctr -> string -> string
536 (** [decrypt] is [encrypt]. *)
537
538 val stream_into : key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
539 (** [stream_into ~key ~ctr dst ~off len] is the raw key stream put into
540 [dst] starting at [off].
541
542 @raise Invalid_argument if [Bytes.length dst - off < len]. *)
543
544 val encrypt_into :
545 key:key ->
546 ctr:ctr ->
547 string ->
548 src_off:int ->
549 bytes ->
550 dst_off:int ->
551 int ->
552 unit
553 (** [encrypt_into ~key ~ctr src ~src_off dst ~dst_off len] produces the key
554 stream into [dst] at [dst_off], and then xors it with [src] at
555 [src_off].
556
557 @raise Invalid_argument
558 if [dst_off < 0 || Bytes.length dst - dst_off < len].
559 @raise Invalid_argument
560 if [src_off < 0 || String.length src - src_off < len]. *)
561
562 val decrypt_into :
563 key:key ->
564 ctr:ctr ->
565 string ->
566 src_off:int ->
567 bytes ->
568 dst_off:int ->
569 int ->
570 unit
571 (** [decrypt_into] is {!encrypt_into}. *)
572
573 (**/**)
574
575 val unsafe_stream_into :
576 key:key -> ctr:ctr -> bytes -> off:int -> int -> unit
577 (** [unsafe_stream_into] is {!stream_into}, but without bounds checks.
578
579 This may cause memory issues if the invariant is violated:
580 - [off >= 0 && Bytes.length buf - off >= len]. *)
581
582 val unsafe_encrypt_into :
583 key:key ->
584 ctr:ctr ->
585 string ->
586 src_off:int ->
587 bytes ->
588 dst_off:int ->
589 int ->
590 unit
591 (** [unsafe_encrypt_into] is {!encrypt_into}, but without bounds checks.
592
593 This may cause memory issues if an invariant is violated:
594 - [dst_off >= 0 && Bytes.length dst - dst_off >= len],
595 - [src_off >= 0 && String.length src - src_off >= len]. *)
596
597 val unsafe_decrypt_into :
598 key:key ->
599 ctr:ctr ->
600 string ->
601 src_off:int ->
602 bytes ->
603 dst_off:int ->
604 int ->
605 unit
606 (** [unsafe_decrypt_into] is {!unsafe_encrypt_into}. *)
607
608 (**/**)
609 end
610
611 (** {e Galois/Counter Mode}. *)
612 module type GCM = sig
613 include AEAD
614
615 val key_sizes : int array
616 (** Key sizes allowed with this cipher. *)
617
618 val block_size : int
619 (** The size of a single block. *)
620 end
621
622 (** {e Counter with CBC-MAC} mode. *)
623 module type CCM16 = sig
624 include AEAD
625
626 val key_sizes : int array
627 (** Key sizes allowed with this cipher. *)
628
629 val block_size : int
630 (** The size of a single block. *)
631 end
632end
633
634module AES : sig
635 module ECB : Block.ECB
636 module CBC : Block.CBC
637 module CTR : Block.CTR with type ctr = int64 * int64
638 module GCM : Block.GCM
639 module CCM16 : Block.CCM16
640end
641
642module DES : sig
643 module ECB : Block.ECB
644 module CBC : Block.CBC
645 module CTR : Block.CTR with type ctr = int64
646end
647
648val accelerated : [ `XOR | `AES | `GHASH ] list
649(** Operations using non-portable, hardware-dependent implementation in this
650 build of the library. *)
651
652(** The ChaCha20 cipher proposed by D.J. Bernstein. *)
653module Chacha20 : sig
654 include AEAD
655
656 val crypt : key:key -> nonce:string -> ?ctr:int64 -> string -> string
657 (** [crypt ~key ~nonce ~ctr data] generates a ChaCha20 key stream using the
658 [key], and [nonce]. The [ctr] defaults to 0. The generated key stream is
659 of the same length as [data], and the output is the XOR of the key stream
660 and [data]. This implements, depending on the size of the [nonce] (8 or 12
661 bytes) both the original specification (where the counter is 8 byte, same
662 as the nonce) and the IETF RFC 8439 specification (where nonce is 12
663 bytes, and counter 4 bytes).
664
665 @raise Invalid_argument
666 if invalid parameters are provided. Valid parameters are: [key] must be
667 32 bytes and [nonce] 12 bytes for the IETF mode (and counter fit into 32
668 bits), or [key] must be either 16 bytes or 32 bytes and [nonce] 8 bytes.
669 *)
670end
671
672(** General stream cipher type. *)
673module type Stream = sig
674 type key
675 type result = { message : string; key : key }
676
677 val of_secret : string -> key
678 val encrypt : key:key -> string -> result
679 val decrypt : key:key -> string -> result
680end
681
682module ARC4 : Stream
683(** {e Alleged Rivest Cipher 4}. *)