upstream: https://github.com/mirage/mirage-crypto
at main 683 lines 22 kB view raw
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}. *)