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
[]
= "offline-protocol-leaf"
= true
= true
= true
= true
= true
= true
= "A constrained leaf node that speaks the Offline Protocol as a never-committing MLS member"
[]
= true
[]
= ["std"]
# `std` forwards to dependencies and gates the unit tests. Nothing in this
# crate reads a clock or draws entropy on its own account in either
# configuration: the time comes in as a parameter and the randomness comes
# from a `getrandom` backend the firmware supplies, which is what makes the
# bare-metal build the same code rather than a reduced one.
= [
"offline-protocol-core/std",
"offline-protocol-sealed/std",
"mls-rs/std",
"mls-rs-core/std",
"mls-rs-crypto-rustcrypto/std",
"serde/std",
"serde_json/std",
"base64/std",
"thiserror/std",
]
# Enables `getrandom`'s custom backend, which a bare-metal target needs
# because `getrandom` has no backend for one and refuses to compile without
# this. Enabling it does **not** supply randomness: the firmware must register
# an implementation (`getrandom::register_custom_getrandom!`) wired to the
# part's hardware entropy source, and MLS key generation is exactly as strong
# as what that returns.
#
# It is not a selection. `getrandom` tries the target's own backend first and
# `custom` last, so on a target that already has one (an operating system,
# WASI) this feature changes nothing, and on a target with none it is the
# only route and the firmware owes the implementation. Deliberately not
# implied by anything, so that a bare-metal build names the obligation it
# takes on.
= ["dep:getrandom", "getrandom/custom"]
# Every dependency below is declared locally rather than inherited with
# `workspace = true`, for the reason ADR 0020 records: cargo silently ignores
# `default-features = false` when it sits next to `workspace = true`, so an
# inherited dependency keeps dragging its `std` feature into the bare-metal
# build and the failure appears as a linker error in someone's firmware rather
# than as a failed check here. `local_dep_versions_match_the_workspace_table`
# in this crate is the counterweight: dropping inheritance means a
# workspace-wide version bump would otherwise stop applying here silently.
[]
= { = "../offline-protocol-core", = "0.30.0", = false }
= { = "../offline-protocol-sealed", = "0.30.0", = false }
# Pinned with `=` deliberately. An interop result is a claim about two exact
# versions (ADR 0021), `tools/mls-interop` pins the same two, and this
# dependency is monitored rather than settled: mls-rs has had no third-party
# security audit and its only bare-metal crypto provider is the one its own
# authors label experimental.
#
# The four features are the leaf profile measured in `tools/embedded-footprint`:
# `private_message` because application messages are `PrivateMessage` and
# nothing works without it, `out_of_order` and `prior_epoch` because a radio
# reorders and drops, and `by_ref_proposal` for the proposals a phone's commit
# can carry. `rfc_compliant` is deliberately absent: it pulls X.509 in for
# about 12 KiB of flash this protocol never uses, since credentials here are
# basic ones carrying an address.
= { = "=0.56.0", = false, = [
"private_message",
"out_of_order",
"prior_epoch",
"by_ref_proposal",
] }
= { = "=0.22.1", = false }
# Named directly because this crate implements two of its traits
# (`GroupStateStorage`, `KeyPackageStorage`) and `mls-rs` does not re-export
# the types they carry. Pinned with the same `=` and for the same reason.
= { = "=0.27.0", = false }
= { = "1.0", = false, = ["derive", "alloc"] }
= { = "1.0", = false, = ["alloc"] }
= { = "0.22", = false, = ["alloc"] }
= { = "2.0", = false }
# `Zeroizing` is in the signature of `GroupStateStorage`, so it is ours to name.
= { = "1", = false }
# Optional and off by default: see the `bare-metal-rng` feature above.
= { = "0.2", = false, = true }
# A processor without compare-and-swap (ESP32-C3, ESP32-C2, every Cortex-M0)
# has no `alloc::sync`, so the reference-counted store handle comes from here
# instead, which is what the pinned mls-rs does for its own handles. Without
# this table the crate does not build on those targets at all.
#
# No atomics backend is chosen here, on purpose. Which one is sound is a fact
# about the chip and the firmware, so the firmware selects it, as
# portable-atomic asks of libraries. The pinned mls-rs selects
# `critical-section` on these targets regardless, so a firmware must link a
# critical-section implementation.
[]
= { = "0.2", = false, = ["alloc"] }
# The host shim for a WebAssembly runtime (`examples/wasi_host_shim.rs`). It
# needs `std` for its standard streams, so `required-features` makes the
# bare-metal and `no_std` WASI builds skip it rather than fail on it, and CI
# builds it for `wasm32-wasip1` in its own step so it cannot rot.
[[]]
= "wasi_host_shim"
= ["std"]