upstream: https://github.com/mirage/mirage-crypto
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: rename internal mirage references to match the fork

The fork was rebranded mirage-crypto -> crypto at commit 87888f69
(initial import) but several internal labels still carried the old
name. Replace them so the visible identity matches the package
naming everywhere:

- src/c/crypto.h: header guard H__MIRAGE_CRYPTO -> H__CRYPTO.
- config/cfg.ml: Configurator.V1.create label "mirage-crypto" -> "crypto".
- rng/entropy.ml: Logs source "mirage-crypto-rng-entropy" -> "crypto-rng-entropy".
- src/crypto.mli: rewrite the top-level docstring to describe the
fork rather than mirage-crypto. The new wording explicitly names
Hannes Mehnert (mirage-crypto upstream maintainer), David Kaloper
Meršinjak (original ocaml-nocrypto author), and Thomas Pornin
(BearSSL author whose ct64 / ctmul64 primitives we vendor).
Includes links to mirage-crypto, ocaml-nocrypto, and BearSSL.
- ec/crypto_ec.mli: "Mirage-crypto-ec implements..." -> "Crypto-ec
implements..."; reference to [mirage-crypto-ec] -> [crypto-ec].
- rng/crypto_rng.mli: replace the dangling references to
Crypto_rng_mirage and Crypto_rng_miou_unix (which never existed
in the fork -- the Mirage and Miou sub-libraries were dropped per
the fork's README) with a reference to Crypto_rng_unix.

Not touched (intentional):
- The mc_* C symbol prefix. Renaming would require touching every
CAML external binding in src/native.mli and the matching C
CAMLprim definitions; that's a much larger surgery and gives
no functional benefit. Filed as future work if anyone cares.
- README.md and LICENSE files -- those carry attribution to the
upstream projects and should stay accurate.
- Comments that document provenance ("TLS regression test from
mirage-crypto", "hand-tuned mirage-crypto code", etc.) -- accurate
attribution.
- CI workflow files (.github/workflows/*.yml, .cirrus.yml,
.test-mirage.sh) -- they reference upstream mirage-crypto package
names and would need separate cleanup; they're not exercised by
the monorepo's CI anyway.

Also includes mechanical ocamlformat reflows in aes_pure.ml,
config/cfg.ml, and test/dune that the harness ran after the
previous commit.

All 4068 tests still pass (C, native OCaml, and Node.js JS paths
all agree byte-for-byte on the differential test vectors).

+77 -61
+3 -2
config/cfg.ml
··· 1 1 let () = 2 - let c = Configurator.V1.create "mirage-crypto" in 2 + let c = Configurator.V1.create "crypto" in 3 3 let ccomp_type_opt = Configurator.V1.ocaml_config_var c "ccomp_type" in 4 4 let arch = 5 5 let defines = ··· 62 62 match ccomp_type_opt with 63 63 | Some "msvc" -> [ "/Wall" ] 64 64 | _ -> 65 - [ "--std=c11"; "-Wall"; "-Wextra"; "-Wpedantic"; "-O3" ] @ hardening_flags 65 + [ "--std=c11"; "-Wall"; "-Wextra"; "-Wpedantic"; "-O3" ] 66 + @ hardening_flags 66 67 in 67 68 let warn_flags = 68 69 (* See #178, there may be false positives on ppc&s390 with no-stringop-overflow *)
+3 -3
ec/crypto_ec.mli
··· 1 1 (** {1 Elliptic curve cryptography} *) 2 2 3 - (** Mirage-crypto-ec implements public key cryptography with named elliptic 4 - curves. Ephemeral key exchanges with {{!Dh}Diffie-Hellman} and 3 + (** Crypto-ec implements public key cryptography with named elliptic curves. 4 + Ephemeral key exchanges with {{!Dh}Diffie-Hellman} and 5 5 {{!Dsa}digital signatures (ECDSA)} are implemented. 6 6 7 7 The arithmetic operations uses code generated by ··· 140 140 (** {2 Misc} *) 141 141 142 142 (** Operations to precompute useful data meant to be hardcoded in 143 - [mirage-crypto-ec] before compilation *) 143 + [crypto-ec] before compilation *) 144 144 module Precompute : sig 145 145 val generator_tables : unit -> string array array array 146 146 (** Return an array of shape (Fe_length * 2, 15, 3) containing multiples of
+3 -3
rng/crypto_rng.mli
··· 28 28 {b Please be aware that the feeding of Fortuna and producing random numbers 29 29 is not thread-safe} (it is on Miou_unix via Pfortuna). 30 30 31 - Suitable entropy feeding of generators are provided by other libraries 32 - {{!Crypto_rng_mirage}mirage-crypto-rng-mirage} (for MirageOS), and 33 - {{!Crypto_rng_miou_unix}mirage-crypto-miou-unix} (for Miou_unix). 31 + Suitable entropy feeding of generators is provided by 32 + {{!Crypto_rng_unix}crypto-rng.unix} (for Unix). The Mirage and Miou 33 + sub-libraries from upstream mirage-crypto have been dropped in this fork. 34 34 35 35 The intention is that "initialize" in the respective sub-library is called 36 36 once, which sets the default generator and registers entropy harvesting
+1 -1
rng/entropy.ml
··· 28 28 *) 29 29 30 30 let src = 31 - Logs.Src.create "mirage-crypto-rng-entropy" ~doc:"Mirage crypto RNG Entropy" 31 + Logs.Src.create "crypto-rng-entropy" ~doc:"Crypto RNG Entropy" 32 32 33 33 module Log = (val Logs.src_log src : Logs.LOG) 34 34
+3 -3
src/c/crypto.h
··· 1 - #if !defined (H__MIRAGE_CRYPTO) 2 - #define H__MIRAGE_CRYPTO 1 + #if !defined (H__CRYPTO) 2 + #define H__CRYPTO 3 3 4 4 #include <stdint.h> 5 5 #include <string.h> ··· 140 140 CAMLprim value 141 141 mc_count_16_be_4_generic (value ctr, value dst, value off, value blocks); 142 142 143 - #endif /* H__MIRAGE_CRYPTO */ 143 + #endif /* H__CRYPTO */
+11 -4
src/crypto.mli
··· 1 1 (** Simpler crypto 2 2 3 - Mirage-crypto is a cryptographic library. 3 + Crypto is a cryptographic library, forked from 4 + {{:https://github.com/mirage/mirage-crypto}mirage-crypto} (maintained by 5 + Hannes Mehnert), itself forked from 6 + {{:https://github.com/mirleft/ocaml-nocrypto}ocaml-nocrypto} (originally 7 + written by David Kaloper Meršinjak). The fork removes the Lwt and Miou 8 + dependencies, keeping only Eio-compatible code, and replaces the 9 + non-constant-time AES and GHASH fallbacks with vendored 10 + {{:https://bearssl.org/}BearSSL} primitives by Thomas Pornin. 4 11 5 12 The overarching API principle is simply mapping inputs to outputs, wherever 6 13 feasible. ··· 9 16 {{!Cipher_block}block ciphers}) are presented as distinct modules sharing 10 17 the same signature. 11 18 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. *) 19 + The opam package crypto-rng provides a cryptographically secure 20 + pseudo-random number generator, the package crypto-pk provides public key 21 + cryptography. *) 15 22 16 23 (**/**) 17 24
+41 -41
src/ocaml/aes_pure.ml
··· 1 1 (** Pure OCaml AES — constant-time bitsliced implementation. 2 2 3 3 This is a direct port of BearSSL's [aes_ct.c] (32-bit bitsliced) and 4 - [aes_ct_enc.c] by Thomas Pornin (MIT license). See 5 - https://bearssl.org/ and https://eprint.iacr.org/2009/191.pdf 6 - (Boyar–Peralta). 4 + [aes_ct_enc.c] by Thomas Pornin (MIT license). See https://bearssl.org/ and 5 + https://eprint.iacr.org/2009/191.pdf (Boyar–Peralta). 7 6 8 - This backend exists for [js_of_ocaml] and [wasm_of_ocaml] targets 9 - where the C primitives are unavailable. Performance is much lower 10 - than the C/AES-NI path: a Fortuna RNG built on top of this can 11 - expect a few hundred KB/s, not the hundreds of MB/s of the C path. 12 - The trade-off is that the operations are constant-time (no table 13 - lookups indexed by secret bytes), so secret keys are not leaked 14 - through cache-timing on hosts where that matters. 7 + This backend exists for [js_of_ocaml] and [wasm_of_ocaml] targets where the 8 + C primitives are unavailable. Performance is much lower than the C/AES-NI 9 + path: a Fortuna RNG built on top of this can expect a few hundred KB/s, not 10 + the hundreds of MB/s of the C path. The trade-off is that the operations are 11 + constant-time (no table lookups indexed by secret bytes), so secret keys are 12 + not leaked through cache-timing on hosts where that matters. 15 13 16 - Two AES blocks are encrypted in parallel via 8 [Int32] words; for 17 - callers that only have one block we pad with zero and discard the 18 - extra output. All temporaries are local; no precomputed tables 19 - indexed by key material exist anywhere in this module. *) 14 + Two AES blocks are encrypted in parallel via 8 [Int32] words; for callers 15 + that only have one block we pad with zero and discard the extra output. All 16 + temporaries are local; no precomputed tables indexed by key material exist 17 + anywhere in this module. *) 20 18 21 19 (* All operations work on 32-bit unsigned values represented as 22 20 Int32.t. We use Int32 (rather than the host int) so that the ··· 30 28 let ( &&& ) = Int32.logand 31 29 let ( ||| ) = Int32.logor 32 30 let lnot32 = Int32.lognot 33 - 34 31 let ( <<< ) a n = Int32.shift_left a n 35 32 let ( >>> ) a n = Int32.shift_right_logical a n 36 - 37 33 let m_55 = 0x55555555l 38 34 let m_aa = 0xAAAAAAAAl 39 35 let m_33 = 0x33333333l ··· 188 184 let ortho q = 189 185 let swapn cl ch s i j = 190 186 let a = q.(i) and b = q.(j) in 191 - q.(i) <- (a &&& cl) ||| ((b &&& cl) <<< s); 192 - q.(j) <- ((a &&& ch) >>> s) ||| (b &&& ch) 187 + q.(i) <- a &&& cl ||| (b &&& cl <<< s); 188 + q.(j) <- a &&& ch >>> s ||| (b &&& ch) 193 189 in 194 190 let swap2 i j = swapn m_55 m_aa 1 i j in 195 191 let swap4 i j = swapn m_33 m_cc 2 i j in ··· 216 212 for i = 0 to 7 do 217 213 let x = q.(i) in 218 214 q.(i) <- 219 - (x &&& 0x000000FFl) 220 - ||| ((x &&& 0x0000FC00l) >>> 2) 221 - ||| ((x &&& 0x00000300l) <<< 6) 222 - ||| ((x &&& 0x00F00000l) >>> 4) 223 - ||| ((x &&& 0x000F0000l) <<< 4) 224 - ||| ((x &&& 0xC0000000l) >>> 6) 225 - ||| ((x &&& 0x3F000000l) <<< 2) 215 + x &&& 0x000000FFl 216 + ||| (x &&& 0x0000FC00l >>> 2) 217 + ||| (x &&& 0x00000300l <<< 6) 218 + ||| (x &&& 0x00F00000l >>> 4) 219 + ||| (x &&& 0x000F0000l <<< 4) 220 + ||| (x &&& 0xC0000000l >>> 6) 221 + ||| (x &&& 0x3F000000l <<< 2) 226 222 done 227 223 228 - let rotr16 x = (x <<< 16) ||| (x >>> 16) 224 + let rotr16 x = x <<< 16 ||| (x >>> 16) 229 225 230 226 let mix_columns q = 231 227 let q0 = q.(0) ··· 236 232 and q5 = q.(5) 237 233 and q6 = q.(6) 238 234 and q7 = q.(7) in 239 - let r0 = (q0 >>> 8) ||| (q0 <<< 24) in 240 - let r1 = (q1 >>> 8) ||| (q1 <<< 24) in 241 - let r2 = (q2 >>> 8) ||| (q2 <<< 24) in 242 - let r3 = (q3 >>> 8) ||| (q3 <<< 24) in 243 - let r4 = (q4 >>> 8) ||| (q4 <<< 24) in 244 - let r5 = (q5 >>> 8) ||| (q5 <<< 24) in 245 - let r6 = (q6 >>> 8) ||| (q6 <<< 24) in 246 - let r7 = (q7 >>> 8) ||| (q7 <<< 24) in 235 + let r0 = q0 >>> 8 ||| (q0 <<< 24) in 236 + let r1 = q1 >>> 8 ||| (q1 <<< 24) in 237 + let r2 = q2 >>> 8 ||| (q2 <<< 24) in 238 + let r3 = q3 >>> 8 ||| (q3 <<< 24) in 239 + let r4 = q4 >>> 8 ||| (q4 <<< 24) in 240 + let r5 = q5 >>> 8 ||| (q5 <<< 24) in 241 + let r6 = q6 >>> 8 ||| (q6 <<< 24) in 242 + let r7 = q7 >>> 8 ||| (q7 <<< 24) in 247 243 q.(0) <- q7 ^^ r7 ^^ r0 ^^ rotr16 (q0 ^^ r0); 248 244 q.(1) <- q0 ^^ r0 ^^ q7 ^^ r7 ^^ r1 ^^ rotr16 (q1 ^^ r1); 249 245 q.(2) <- q1 ^^ r1 ^^ r2 ^^ rotr16 (q2 ^^ r2); ··· 279 275 word by replicating it across all 8 lanes; that path is 280 276 constant-time because bitslice_sbox is. *) 281 277 282 - let rcon = [| 0x01l; 0x02l; 0x04l; 0x08l; 0x10l; 0x20l; 0x40l; 0x80l; 0x1Bl; 0x36l |] 278 + let rcon = 279 + [| 0x01l; 0x02l; 0x04l; 0x08l; 0x10l; 0x20l; 0x40l; 0x80l; 0x1Bl; 0x36l |] 283 280 284 281 let dec32le src off = 285 282 let b0 = Int32.of_int (Char.code (String.get src off)) in ··· 290 287 291 288 let enc32le dst off w = 292 289 Bytes.set dst off (Char.chr (Int32.to_int (w &&& 0xFFl))); 293 - Bytes.set dst (off + 1) (Char.chr (Int32.to_int ((w >>> 8) &&& 0xFFl))); 294 - Bytes.set dst (off + 2) (Char.chr (Int32.to_int ((w >>> 16) &&& 0xFFl))); 295 - Bytes.set dst (off + 3) (Char.chr (Int32.to_int ((w >>> 24) &&& 0xFFl))) 290 + Bytes.set dst (off + 1) (Char.chr (Int32.to_int (w >>> 8 &&& 0xFFl))); 291 + Bytes.set dst (off + 2) (Char.chr (Int32.to_int (w >>> 16 &&& 0xFFl))); 292 + Bytes.set dst (off + 3) (Char.chr (Int32.to_int (w >>> 24 &&& 0xFFl))) 296 293 297 294 let sub_word x = 298 295 let q = Array.make 8 x in ··· 323 320 let k = ref 0 in 324 321 for i = nk to nkf - 1 do 325 322 if !j = 0 then begin 326 - tmp := (!tmp <<< 24) ||| (!tmp >>> 8); 323 + tmp := !tmp <<< 24 ||| (!tmp >>> 8); 327 324 tmp := sub_word !tmp ^^ rcon.(!k) 328 325 end 329 326 else if nk > 6 && !j = 4 then tmp := sub_word !tmp; ··· 347 344 let i = ref 0 in 348 345 let j = ref 0 in 349 346 while !i < nkf do 350 - comp_skey.(!i) <- (skey.(!j) &&& m_55) ||| (skey.(!j + 1) &&& m_aa); 347 + comp_skey.(!i) <- skey.(!j) &&& m_55 ||| (skey.(!j + 1) &&& m_aa); 351 348 incr i; 352 349 j := !j + 2 353 350 done; ··· 472 469 i := !i + 2 473 470 done; 474 471 if !i < blocks then 475 - encrypt_one_block skey num_rounds src (soff + (!i * 16)) dst (doff + (!i * 16)); 472 + encrypt_one_block skey num_rounds src 473 + (soff + (!i * 16)) 474 + dst 475 + (doff + (!i * 16)); 476 476 (* Wipe the expanded schedule before return -- analogous to mc_secure_bzero. *) 477 477 Array.fill skey 0 (Array.length skey) 0l
+12 -4
test/dune
··· 57 57 (target test_pure.c.out) 58 58 (deps test_pure_c.exe) 59 59 (action 60 - (with-stdout-to %{target} (run %{deps})))) 60 + (with-stdout-to 61 + %{target} 62 + (run %{deps})))) 61 63 62 64 (rule 63 65 (target test_pure.ocaml.out) 64 66 (deps test_pure.exe) 65 67 (action 66 - (with-stdout-to %{target} (run %{deps})))) 68 + (with-stdout-to 69 + %{target} 70 + (run %{deps})))) 67 71 68 72 (rule 69 73 (alias runtest) ··· 74 78 ; Node.js runner. We invoke node on the .bc.js artifact directly. 75 79 ; If node is not installed the alias is empty and CI on hosts 76 80 ; without node still passes the rest of the test suite. 81 + 77 82 (rule 78 83 (target test_pure.js.out) 79 84 (deps test_pure.bc.js) 80 85 (action 81 - (with-stdout-to %{target} (bash "node %{deps} || true")))) 86 + (with-stdout-to 87 + %{target} 88 + (bash "node %{deps} || true")))) 82 89 83 90 (rule 84 91 (alias runtest-js) ··· 88 95 89 96 (alias 90 97 (name runtest) 91 - (deps (alias runtest-js))) 98 + (deps 99 + (alias runtest-js)))