pamoja-session
Encrypted, authenticated sessions for pamoja: X25519 key agreement (RFC 7748) and HKDF-SHA256 (RFC 5869) derive a session key, then ChaCha20-Poly1305 (RFC 8439) protects each message with counter nonces and an anti-replay window, so two devices that know each other's keys share a confidential, tamper-evident link, no_std and allocation-free. The secured-channel half ahead of the rustls/DTLS driver.
The same capability in every language
| Language | Package | Reference |
|---|---|---|
| Rust | pamoja-session |
reference, docs.rs, install |
| TypeScript | @pamoja/session |
reference, install |
| Python | pamoja-session |
reference, install |
| C# | Pamoja.Session |
reference, install |
Encrypted, authenticated sessions for the pamoja SDK.
pamoja-security proves a payload came from a
device and was not altered. This crate adds the other half a networked link needs:
confidentiality and a fresh, ordered, replay-protected channel, so a reading is
not just trustworthy but private, and a captured message cannot be replayed to
reopen a valve or re-trigger an alarm.
Two devices that each hold the other's authenticated public key agree a session
key with Session::establish and then exchange messages with Session::seal
and Session::open. The whole exchange is built from published standards and
the tests are pinned to their reference vectors:
- X25519 key agreement, RFC 7748, so neither side ever sends the key.
- HKDF-SHA256, RFC 5869, to derive a per-session key bound to both public keys.
- ChaCha20-Poly1305, RFC 8439, to encrypt and authenticate each message; chosen because the cheap hardware this SDK targets rarely has AES acceleration.
Establishing a session is deterministic given the keys and salt, and every
operation works in place on caller-owned buffers, so the crate is no_std and
allocation-free and runs unchanged on a microcontroller. It is the secured-channel
groundwork the security pillar builds on, ahead of full transport TLS/DTLS.
Authenticating the peer
Key agreement gives a private channel; it does not by itself say who is on the
other end. The peer's AgreementPublicKey must be authenticated out of band,
by pinning it at provisioning time or by having it signed with the peer's
pamoja-security identity. Without that, the channel is confidential but open to
a man in the middle.
Examples
use ;
// Each device holds its own seed and the other's authenticated public key.
let sensor = from_seed;
let gateway = from_seed;
// A fresh salt is exchanged in the clear to start the session.
let salt = ;
let mut a = establish;
let mut b = establish;
// Seal a reading; the device id rides along as authenticated-but-readable data.
let mut reading = *b"tank: 18%";
let sealed = a.seal;
// The gateway opens it, recovering the reading and proving it is authentic.
b.open.expect;
assert_eq!;
// A replay of the same message is refused.
assert!;
License
MIT - part of the pamoja workspace: one memory-safe Rust core with bindings for every language.