The Update Framework (TUF) security model over COSE_Sign1/CBOR
0

Configure Feed

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

*: migrate every digestif consumer to ocaml-hash

Tree-wide mechanical migration (Digestif.* -> Hash.*, dune and opam
deps digestif -> ocaml-hash) across 43 packages, dropping digestif
from the dependency graph entirely (root.opam no longer lists it).
Blob digests, git object ids, KEX exchange hashes, JWT/COSE/X.509
signatures and every other SHA-256 user now ride the hardware path on
CPUs that have it.

Five libraries had an internal hash.ml that would shadow the Hash
library inside their own compilation units; their internal module is
renamed by what it actually is, with the public alias kept so
consumers (Irmin.Hash, Git.Hash, Tpm.Hash, ...) are unchanged:

- irmin, ocaml-git: Object_hash (content-addressed object ids)
- ocaml-scitt, ocaml-sigstore: Hash_alg (algorithm registries)
- ocaml-tpm: Hashing (digest/HMAC/KDFa over TPM algorithms)

Semantic adjustments the rename surfaced:

- x509: the OID<->hash tables lose their arms for algorithms the
hash library does not carry (SHA-3, BLAKE2, RIPEMD, WHIRLPOOL);
Hash.kind is closed over the six supported algorithms so the
catch-all arms were dead.
- sigstore: bundles declaring SHA-3 digests now fail verification
loudly (Invalid_argument) instead of mapping to an unimplemented
kind; the protobuf enum still parses.
- x509/jwt: local [let module Hash = (val module_of ...)] bindings
renamed to H -- they would shadow the library inside their scope.
- irmin re-exports the raw SHA-1/SHA-256 implementations through
Object_hash so its schema instantiations need no second name for
the library under the public Hash alias.

SSH throughput is unchanged (170/537/460 MB/s socketpair / 2-domain /
2-process, same as the digestif baseline): the negotiated transport
cipher is chacha20-poly1305, whose MAC is Poly1305, so SHA-256 only
runs in the handshake. SSH's data-path ceiling remains nox-crypto's
scalar ChaCha20/Poly1305.

All migrated package suites pass (ssh, tls, x509, paseto, jwt, kdf,
git, tpm, scitt, sigstore, oci, srp, spake2, cose, bpsec, hash).

+27 -11
+1 -1
dune-project
··· 29 29 (nox-json (>= 0.1.0)) 30 30 (nox-x509 (>= 1.0.0)) 31 31 (nox-crypto-ec (>= 1.0.0)) 32 - (digestif (>= 1.2.0)) 32 + ocaml-hash 33 33 (ptime (>= 1.1.0)) 34 34 (fmt (>= 0.9)) 35 35 (alcotest :with-test)
+1 -1
fuzz/dune
··· 13 13 nox-crypto-ec 14 14 nox-crypto-rng.unix 15 15 nox-x509 16 - digestif 16 + ocaml-hash 17 17 ptime 18 18 alcobar)) 19 19
+1 -1
lib/core/dune
··· 1 1 (library 2 2 (name tuf_core) 3 3 (public_name tuf.core) 4 - (libraries digestif ptime fmt)) 4 + (libraries ocaml-hash ptime fmt))
+1 -1
lib/core/meta.ml
··· 1 1 type algorithm = [ `Ed25519 ] 2 2 type key = { algorithm : algorithm; public : string } 3 3 4 - let keyid k = Digestif.SHA256.(to_hex (digest_string k.public)) 4 + let keyid k = Hash.SHA256.(to_hex (digest_string k.public)) 5 5 6 6 type role = { keyids : string list; threshold : int } 7 7 type hash = { algorithm : string; digest : string }
+9 -1
lib/cose/dune
··· 1 1 (library 2 2 (name tuf_cose) 3 3 (public_name tuf.cose) 4 - (libraries tuf.core cose nox-cbor nox-x509 nox-crypto-ec digestif ptime fmt)) 4 + (libraries 5 + tuf.core 6 + cose 7 + nox-cbor 8 + nox-x509 9 + nox-crypto-ec 10 + ocaml-hash 11 + ptime 12 + fmt))
+1 -1
test/dune
··· 10 10 nox-x509 11 11 nox-crypto-ec 12 12 nox-crypto-rng.unix 13 - digestif 13 + ocaml-hash 14 14 ptime 15 15 alcotest))
+1 -1
test/helpers/dune
··· 8 8 nox-x509 9 9 nox-crypto-ec 10 10 nox-crypto-rng.unix 11 - digestif 11 + ocaml-hash 12 12 ptime 13 13 alcotest))
+2 -2
test/helpers/test_helpers.ml
··· 62 62 } 63 63 in 64 64 let blob = "hello-artifact" in 65 - let digest = Digestif.SHA256.(to_hex (digest_string blob)) in 65 + let digest = Hash.SHA256.(to_hex (digest_string blob)) in 66 66 let target = 67 67 { 68 68 Meta.path = "images/web"; ··· 140 140 } 141 141 in 142 142 let vblob = "vendor-app" in 143 - let vdigest = Digestif.SHA256.(to_hex (digest_string vblob)) in 143 + let vdigest = Hash.SHA256.(to_hex (digest_string vblob)) in 144 144 let vtarget = 145 145 { 146 146 Meta.path = "images/vendor/app";
+8
test/interop/python-tuf/dune
··· 9 9 (libraries tuf.core tuf.json ptime alcotest) 10 10 (deps 11 11 (source_tree traces))) 12 + 13 + ; Regenerate the committed traces: REGEN=1 dune build @regen-traces. 14 + 15 + (rule 16 + (alias regen-traces) 17 + (deps 18 + (alias traces/regen)) 19 + (action (progn)))
+1 -1
test/test_client.ml
··· 314 314 delegations = Some { Meta.keys = [ vkey ]; roles = [ deleg ] }; 315 315 } 316 316 in 317 - let digest = Digestif.SHA256.(to_hex (digest_string "evil")) in 317 + let digest = Hash.SHA256.(to_hex (digest_string "evil")) in 318 318 let evil = 319 319 { 320 320 Meta.path = "evil/path";
+1 -1
tuf.opam
··· 22 22 "nox-json" {>= "0.1.0"} 23 23 "nox-x509" {>= "1.0.0"} 24 24 "nox-crypto-ec" {>= "1.0.0"} 25 - "digestif" {>= "1.2.0"} 25 + "ocaml-hash" 26 26 "ptime" {>= "1.1.0"} 27 27 "fmt" {>= "0.9"} 28 28 "alcotest" {with-test}