-
Notifications
You must be signed in to change notification settings - Fork 48
Expand file tree
/
Copy pathCargo.toml
More file actions
185 lines (175 loc) · 11.7 KB
/
Copy pathCargo.toml
File metadata and controls
185 lines (175 loc) · 11.7 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
[workspace]
resolver = "2"
members = ["firmware", "rsk-wipe", "crates/rsk-sdk", "crates/rsk-fs", "crates/rsk-usb", "crates/rsk-crypto", "crates/rsk-fido", "crates/rsk-openpgp", "crates/rsk-rsa", "crates/rsk-ec", "crates/rsk-sha512", "crates/rsk-devconf", "crates/rsk-mgmt", "crates/rsk-oath", "crates/rsk-otp", "crates/rsk-piv", "crates/rsk-rescue", "crates/rsk-vendor", "crates/rsk-device", "crates/rsk-display", "crates/rsk-store", "crates/rsk-led", "crates/rsk-phy", "crates/rsk-ui", "crates/rsk-bip39", "crates/rsk-slip39", "crates/rsk-mldsa", "crates/rsk-bench"]
# Embassy crates are versioned together; pin them all to the same git source so
# they stay mutually compatible. We track `branch = "main"`, not a crates.io
# release, because embassy-rp's RP2350 (thumbv8m) support has historically landed
# on main well ahead of published releases. This stays reproducible: the exact
# commit is frozen in Cargo.lock (and re-pinned by content hash for the nix build
# in flake.nix), so `branch = "main"` names the source, not a moving target —
# nothing updates until someone runs `cargo update` / bumps the lock on purpose.
# Bump cadence: do it deliberately (not routinely), re-run the full gate, and do
# an on-device smoke (USB enumerate + a FIDO/CCID round-trip) before trusting it.
[workspace.dependencies]
embassy-executor = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-rp = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-time = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-usb = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-futures = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-embedded-hal = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
embassy-sync = { git = "https://github.com/embassy-rs/embassy", branch = "main" }
# The RP2350 PAC, pinned to the exact revision embassy-rp uses (its `pac` re-export
# is pub(crate)); the rescue applet reads OTP_DATA_RAW for the secure-boot status.
rp-pac = { git = "https://github.com/embassy-rs/rp-pac", rev = "c2e27609b021c444f634673155318977d7f0bdf6", features = ["rp235x"] }
rsk-sdk = { path = "crates/rsk-sdk" }
rsk-fs = { path = "crates/rsk-fs" }
rsk-usb = { path = "crates/rsk-usb" }
rsk-crypto = { path = "crates/rsk-crypto" }
rsk-fido = { path = "crates/rsk-fido" }
rsk-openpgp = { path = "crates/rsk-openpgp" }
rsk-rsa = { path = "crates/rsk-rsa" }
rsk-ec = { path = "crates/rsk-ec" }
# Fast byte-identical SHA-512/384 for the Cortex-M33 — a compact rolled
# compression that fits the XIP cache, replacing `sha2`'s ~28 KB unrolled soft
# backend on the FIDO key-derivation ratchet without changing any credential key.
rsk-sha512 = { path = "crates/rsk-sha512" }
rsk-devconf = { path = "crates/rsk-devconf" }
rsk-mgmt = { path = "crates/rsk-mgmt" }
rsk-oath = { path = "crates/rsk-oath" }
rsk-otp = { path = "crates/rsk-otp" }
rsk-piv = { path = "crates/rsk-piv" }
rsk-rescue = { path = "crates/rsk-rescue" }
# The vendor AID (counter, LED, core1 stats, benches, reboot) — firmware-local
# until the emulator needed it too; the hardware sits behind its `Platform`.
rsk-vendor = { path = "crates/rsk-vendor" }
# The applet wiring shared by the firmware and the emulator.
rsk-device = { path = "crates/rsk-device" }
rsk-display = { path = "crates/rsk-display" }
# The two-partition sequential-storage backend the device runs.
rsk-store = { path = "crates/rsk-store" }
rsk-led = { path = "crates/rsk-led" }
# The `EF_PHY` TLV record — USB identity, LED wiring, the interface mask. Shared
# by the rescue and FIDO applets, rsk-device, rsk-display and the boot path; it
# lived inside rsk-rescue and was the one applet→applet edge FIDO still took.
rsk-phy = { path = "crates/rsk-phy" }
rsk-ui = { path = "crates/rsk-ui" }
# On-device BIP-39 encode for the trusted-display recovery-phrase screen (display-gated).
rsk-bip39 = { path = "crates/rsk-bip39" }
# On-device SLIP-39 (Shamir) share encode for the trusted-display recovery screen
# (display-gated). Mirrors the host `shamir_mnemonic` exactly so `rsk backup restore` recombines.
rsk-slip39 = { path = "crates/rsk-slip39" }
# Stack-optimized ML-DSA (FIPS 204) for ML-DSA-44 and -65 — streams the matrix A
# so -65 fits the RP2350 main stack. Host-tested against NIST ACVP KATs + Kani.
rsk-mldsa = { path = "crates/rsk-mldsa" }
# Robust summary stats for the on-device latency harness — used only by the
# firmware `bench` feature (a debug/measurement build, never shipped). Host-tested
# + Kani-proved; the device computes the summary so the reported number is gated.
rsk-bench = { path = "crates/rsk-bench" }
# Trusted-display driver stack — compiled ONLY into the `display` firmware flavor
# (and rsk-ui's host tests), never the standard key (all `dep:`-gated). embedded-
# graphics: no_std 2D text/primitives + the `DrawTarget` trait the renderer is
# generic over; mipidsi supplies the ST7789 color-order and inversion options.
embedded-graphics = { version = "0.8", default-features = false }
mipidsi = { version = "0.10" }
# Keyed 128-bit damage tags stop untrusted display text from choosing a tile-hash
# collision. SipHash is small, no_std, and already present in Cargo.lock.
siphasher = { version = "1.0", default-features = false }
minicbor = { version = "2.2", default-features = false }
p256 = { version = "0.14", default-features = false, features = ["ecdsa", "arithmetic", "ecdh"] }
# Additional FIDO2 signing curves; same 0.14 RustCrypto ecosystem as p256.
p384 = { version = "0.14", default-features = false, features = ["ecdsa", "arithmetic", "ecdh"] }
p521 = { version = "0.14", default-features = false, features = ["ecdsa", "arithmetic", "ecdh"] }
k256 = { version = "0.14", default-features = false, features = ["ecdsa", "arithmetic", "ecdh"] }
# Brainpool for the OpenPGP applet. The bp256/bp384 wrappers are still 0.14.0-rc.15
# (no stable release yet), but their ecdsa/elliptic-curve/primeorder deps resolve to
# the SAME stable 0.14 line as the NIST curves above — one EC generation, no
# duplication. The looped crypto-bigint field backend is picked in .cargo/config
# (`bp*_backend="bigint"`) — smaller than fiat, and brainpool is not a hot path.
bp256 = { version = "=0.14.0-rc.15", default-features = false, features = ["ecdsa", "arithmetic", "sha256"] }
bp384 = { version = "=0.14.0-rc.15", default-features = false, features = ["ecdsa", "arithmetic", "sha384"] }
# ecdsa 0.17 / elliptic-curve 0.14: the single EC generation shared by every curve.
# `ecdsa` is named directly for the brainpool SigningKey (bp* don't alias it),
# `elliptic-curve` for brainpool ECDH.
ecdsa = { version = "0.17", default-features = false, features = ["algorithm"] }
elliptic-curve = { version = "0.14", default-features = false, features = ["ecdh", "arithmetic", "sec1"] }
# EdDSA (Ed25519) — OKP key, deterministic 64-byte signature.
ed25519-dalek = { version = "2", default-features = false, features = ["zeroize"] }
# X25519 ECDH for OpenPGP Cv25519. Same curve25519-dalek 4 backend as
# ed25519-dalek, so no version split. The bare `x25519()` needs no extra feature.
x25519-dalek = { version = "2", default-features = false }
# PQC. ml-kem = ML-KEM (FIPS 203) encapsulation, scaffolding for a future PQC
# PIN/UV protocol. no_std, no alloc, pure Rust. (ML-DSA signatures are the
# in-tree `rsk-mldsa` crate above.)
ml-kem = { version = "0.3.2", default-features = false, features = ["zeroize"] }
# RustCrypto (no_std). Pinned together; bump as a set.
# SHA-1 is for the YKOATH HOTP/TOTP PRF only (RFC 4226 mandates HMAC-SHA1).
sha1 = { version = "0.10", default-features = false }
sha2 = { version = "0.10", default-features = false }
# The digest 0.10 core_api surface `rsk-sha512` implements its Sha512/Sha384
# cores on (same resolved 0.10.7 sha2/hmac/hkdf already pin — no new version).
digest = { version = "0.10", default-features = false, features = ["core-api"] }
hmac = { version = "0.12", default-features = false }
# RFC 6979 deterministic ECDSA nonces — already in the tree transitively via
# `ecdsa`; a direct dep so `ec.rs` can derive `k` itself and swap the crate's
# generic `k·G` for the fixed-base comb while keeping byte-identical signatures.
rfc6979 = { version = "0.6", default-features = false }
hkdf = { version = "0.12", default-features = false }
# `zeroize` wipes the expanded round keys when a cipher instance drops.
aes = { version = "0.8", default-features = false, features = ["zeroize"] }
# 3DES for the legacy PIV management-key algorithm only; default is AES-192.
des = { version = "0.8", default-features = false, features = ["zeroize"] }
cbc = { version = "0.1", default-features = false, features = ["block-padding"] }
cfb-mode = { version = "0.8", default-features = false }
aes-gcm = { version = "0.10", default-features = false, features = ["aes"] }
chacha20poly1305 = { version = "0.10", default-features = false }
zeroize = { version = "1", default-features = false }
# The bignum `rsk-rsa` is arithmetic over. On-card RSA keygen drives
# `prime::probably_prime` directly so the prime search can yield between
# candidates (the CCID keepalive); `zeroize` because every key path here holds
# secret limbs. Features are what the `rsa` crate selected before it was dropped.
num-bigint-dig = { version = "0.8.6", default-features = false, features = ["i128", "prime", "zeroize"] }
# `Integer::lcm` / `is_even` over that bignum: num-bigint-dig implements the
# trait for `BigUint` but does not re-export it, so naming it needs the crate.
# Already in the tree — it is num-bigint-dig's own dependency.
num-integer = { version = "0.1", default-features = false }
[profile.release]
codegen-units = 1
# Keep symbols; UF2 size unaffected (debug info isn't flashed). Load-bearing:
# check.sh's `debug_vendor_commands_absent` reads these names out of the ELF.
debug = 2
lto = "fat"
opt-level = "s" # our crates stay size-optimized…
# …but speed-optimize the dependencies — the pure-Rust elliptic-curve arithmetic
# (p384/p521 especially) is a tight big-int multiply loop that `opt-level="s"`
# penalizes badly on the in-order Cortex-M33 (a P-384 makeCredential takes ~3 s
# at "s"). opt-level 3 here fixes that without bloating our glue.
[profile.release.package."*"]
opt-level = 3
# rsk-sha512 is the ONE crate where size IS speed: at "s" its SHA-512 compression
# stays a compact rolled loop that fits the RP2350 XIP cache; at "3" it unrolls to
# ~28 KB and thrashes the cache (~40× slower — exactly the `sha2` problem it
# replaces). Workspace members already default to "s", but pin it so the property
# survives any future base-profile change. (Inverse of the EC crates above, where
# unrolling wins.)
[profile.release.package.rsk-sha512]
opt-level = "s"
# The display renderer is a pixel-generation hot path. Keep it speed-optimized;
# its retained scene prevents the larger loops from multiplying across bands.
[profile.release.package.rsk-ui]
opt-level = 3
[profile.release.package.rsk-display]
opt-level = 3
[profile.dev]
opt-level = "s" # embassy/HAL needs some opt even in dev to fit/behave
# Vendored sequential-storage 8.0.0 carrying local changes confined to
# `src/map.rs`; third_party/sequential-storage.patch enumerates them and is the
# record. The headline: the map iterator (`MapItemIter::next`) warms the
# key-pointer cache from the full-store scan the boot already runs, so the first
# credential enumeration after a power-cycle is O(1) per key instead of a cold
# backward ring-scan (~9 s at 256 passkeys). The rest harden that walk's
# completion gate against a flash read fault and fix an upstream torn-remove
# rollback. This is the flash KV store that holds every sealed secret, so the
# fork is deliberately kept that narrow — one file, and the patch says which
# functions; upstream tracks the idea in tweedegolf/sequential-storage#105.
[patch.crates-io]
sequential-storage = { path = "third_party/sequential-storage" }