ssh-stamp 1.0.4

SSH to UART bridge firmware core for microcontrollers
Documentation
# SPDX-FileCopyrightText: 2025 Roman Valls, 2025
# SPDX-FileCopyrightText: 2026 Marko Malenic <mmalenic1@gmail.com>
#
# SPDX-License-Identifier: GPL-3.0-or-later

[package]
name = "ssh-stamp"
description = "SSH to UART bridge firmware core for microcontrollers"
documentation = "https://docs.rs/ssh-stamp"
readme = "README.md"
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
homepage.workspace = true
keywords.workspace = true
categories.workspace = true
# Keep the published crate to the library sources; everything else in the repo
# root (docs/, test/, .cargo/, editor config) is not needed to build it.
include = ["/src/**", "/build.rs", "/Cargo.toml", "/README.md", "/LICENSE", "/LICENSES/*"]
authors = [
    "Julio Beltran Ortega <jubeormk1@gmail.com>",
    "Anthony Tambasco <anthony.tambasco@fastmail.com>",
    "Roman Valls Guimera <brainstorm@nopcode.org>",
    "Marko Malenic <mmalenic1@gmail.com>",
]

[package.metadata.docs.rs]
features = ["sftp-ota", "can", "ipv6"]
rustdoc-args = ["--cfg", "docsrs"]

[lib]

[workspace]
members = [
    "ssh-stamp-hal",
    "boards/ssh-stamp-esp/ssh-stamp-esp32",
    "boards/ssh-stamp-esp/ssh-stamp-esp32-boards",
    "boards/ssh-stamp-esp/ssh-stamp-esp32-hil",
    "ssh-stamp-ota",
    "xtask",
]
# What a `cargo test` / `build` / `check` at the root operates on. Any crates
# that are buildable on the host are here. The firmware crates are left out
# and must be run using the `cargo xtask <target> <cargo command>` syntax.
default-members = [".", "ssh-stamp-ota", "xtask"]

[workspace.package]
version = "1.0.4"
edition = "2024"
license = "GPL-3.0-or-later"
repository = "https://github.com/brainstorm/ssh-stamp"
homepage = "https://github.com/brainstorm/ssh-stamp"
keywords = ["ssh", "embedded", "esp32", "uart", "no-std"]
categories = ["embedded", "no-std", "network-programming"]

[workspace.lints.clippy]
mem_forget = "warn"
await_holding_lock = "warn"
pedantic = "warn"
large_futures = { level = "allow", priority = 1 }
default_trait_access = { level = "allow", priority = 1 }

[lints]
workspace = true

[workspace.dependencies]
# Workspace crates. Path dependencies need a version to be publishable; keep
# these in step with `workspace.package.version`.
ssh-stamp = { path = ".", version = "1.0.4", default-features = false }
ssh-stamp-hal = { path = "ssh-stamp-hal", version = "1.0.4" }
ssh-stamp-esp32 = { path = "boards/ssh-stamp-esp/ssh-stamp-esp32", version = "1.0.4", default-features = false }
ssh-stamp-esp32-boards = { path = "boards/ssh-stamp-esp/ssh-stamp-esp32-boards", version = "1.0.4" }
ssh-stamp-ota = { path = "ssh-stamp-ota", version = "1.0.4" }

# Async runtime
embassy-sync = "0.8"
embassy-executor = { version = "0.10" }
embassy-time = { version = "0.5" }
embassy-futures = "0.1.2"

# Collections
heapless = "0.9"

# ESP32
esp-hal = { version = "1.2", features = ["unstable", "log-04"] }
# Build-time configuration.
esp-config = { version = "0.8", default-features = false }

# SSH protocol
sunset = { version = "0.6.0", default-features = false, features = [
    "openssh-key",
    "embedded-io",
    "mlkem",
] }
sunset-async = { version = "0.6.0", default-features = false, features = [
    "multi-thread",
] }
sunset-sshwire-derive = { version = "0.3.0", default-features = false }
sunset-sftp = { version = "0.2.0", default-features = false }

# Crypto
# The compact backend has a small speed impact, but is significantly smaller so it's a
# worthwhile change.
sha2 = { version = "0.10", default-features = false, features = [
    "force-soft-compact",
] }
rustc-hash = { version = "2.1", default-features = false }
bcrypt = { version = "0.17", default-features = false }
subtle = { version = "2", default-features = false }
hmac = { version = "0.12", default-features = false }
digest = { version = "0.10", default-features = false, features = [
    "rand_core",
    "subtle",
] }

# Storage
embedded-storage = "0.3.1"
embedded-storage-async = "0.4"

# Networking
edge-dhcp = "0.7"
edge-nal = "0.6"
edge-nal-embassy = "0.8"
embassy-net = { version = "0.8", features = [
    "tcp",
    "udp",
    "dhcpv4",
    "medium-ethernet",
] }
smoltcp = { version = "0.12", default-features = false, features = [
    "medium-ethernet",
    "socket-raw",
] }

# Utilities
log = "0.4"
static_cell = { version = "2.1" }
once_cell = { version = "1", features = [
    "critical-section",
], default-features = false }
portable-atomic = "1"
snafu = { version = "0.8", default-features = false }
pastey = "0.1"
embedded-io-async = "0.7"
embassy-embedded-hal = "0.6"
embedded-can = "0.4"

[dependencies]
ssh-stamp-ota = { workspace = true }
ssh-stamp-hal = { workspace = true }

sha2 = { workspace = true }
rustc-hash = { workspace = true }

cfg-if = "1"
esp-config = { workspace = true }
ed25519-dalek = { version = "3", default-features = false }
embassy-executor = { workspace = true }
embassy-net = { workspace = true }
smoltcp = { workspace = true }
embassy-time = { workspace = true }
embedded-io-async = { workspace = true }
embedded-can = { workspace = true, optional = true }
hex = { version = "0.4", default-features = false }
log = { workspace = true }
ssh-key = { version = "0.7.0-rc.11", default-features = false, features = ["ed25519"] }
sunset = { workspace = true }
sunset-async = { workspace = true }
sunset-sshwire-derive = { workspace = true }
sunset-sftp = { workspace = true }
getrandom = { version = "0.4" }
embassy-sync = { workspace = true }
heapless = { workspace = true }
embassy-futures = { workspace = true }
embedded-storage = { workspace = true }
bcrypt = { workspace = true }
subtle = { workspace = true }
hmac = { workspace = true }
digest = { workspace = true }
embedded-storage-async = { workspace = true }
portable-atomic = { workspace = true }
snafu = { workspace = true }
pastey = { workspace = true }

[dev-dependencies]
embedded-storage-inmemory = "0.1"

[build-dependencies]
esp-config = { version = "0.8", features = ["build"] }

[profile.dev]
opt-level = 0
debug = 2
debug-assertions = true

[profile.release]
codegen-units = 1
debug = 2
debug-assertions = true
incremental = false
lto = 'fat'
opt-level = "s"
overflow-checks = true
panic = "abort"

[profile.dev.package.esp-storage]
opt-level = "s"

[profile.dev.package.esp-radio]
opt-level = "s"

[features]
default = []

# Enables IPv6 addressing.
ipv6 = ["embassy-net/proto-ipv6"]

# Enables the SFTP OTA Subsystem. Use packer to pack a binary and PUT it over sftp
sftp-ota = ["ssh-stamp-ota/sftp"]

# Enables CAN bus tunnelling over SSH via the "can" subsystem
can = ["dep:embedded-can"]
mem-probe = []