Skip to main content

Session

Struct Session 

Source
pub struct Session { /* private fields */ }
Expand description

A confidential, tamper-evident, replay-protected channel with one peer.

A session holds the agreed key, the counter for the messages this device sends, and a sliding window of the counters it has accepted from the peer. Sealing a message encrypts it and stamps it with the next counter; opening one verifies it and rejects anything that fails authentication or repeats a counter.

A session is deliberately not Clone: two copies would reuse counters and so reuse nonces, which breaks the AEAD’s guarantees. Establish a fresh session instead.

§Examples

use pamoja_session::{AgreementKey, Role, Session};

// Each device is provisioned with its own seed and knows the other's public key.
let fridge = AgreementKey::from_seed(&[1u8; 32]);
let gateway = AgreementKey::from_seed(&[2u8; 32]);

// A fresh salt is agreed in the clear at the start of each session.
let salt = [9u8; 16];
let mut device = Session::establish(&fridge, &gateway.public(), &salt, Role::Initiator);
let mut peer = Session::establish(&gateway, &fridge.public(), &salt, Role::Responder);

// The device seals a reading; the ciphertext, counter, and tag go on the wire.
let mut message = *b"4.8C";
let sealed = device.seal(&mut message, b"fridge-1");

// The gateway opens it, recovering the reading and proving it is authentic.
peer.open(&sealed, &mut message, b"fridge-1").expect("authentic message");
assert_eq!(&message, b"4.8C");

Implementations§

Source§

impl Session

Source

pub fn establish( local: &AgreementKey, peer: &AgreementPublicKey, salt: &[u8], role: Role, ) -> Self

Establishes a session with a peer from this device’s agreement key and the peer’s authenticated public key.

Both devices call this with the same salt and opposite Roles and arrive at the same key. The salt is a fresh per-session value the two sides exchange in the clear before sealing anything; reusing a salt with the same pair of keys reuses the session key, so it must change each session (a counter kept in power-loss-safe storage, or a nonce from a handshake, both work).

§Arguments
  • local - this device’s key-agreement secret.
  • peer - the peer’s public key, already authenticated by pinning or signature.
  • salt - the fresh per-session salt both sides share.
  • role - whether this device is the Role::Initiator or Role::Responder.
§Returns

A session ready to seal and open messages with the peer.

Source

pub fn seal(&mut self, buf: &mut [u8], aad: &[u8]) -> Sealed

Seals a message for the peer, encrypting buf in place and stamping it with the next counter.

The associated data aad is authenticated but not encrypted, so it is readable on the wire yet cannot be altered: a device identifier or a routing header belongs here. After this returns, buf holds the ciphertext and the returned Sealed holds the counter and tag to send with it.

§Arguments
  • buf - the plaintext, replaced in place by the ciphertext of equal length.
  • aad - associated data to authenticate alongside the message.
§Returns

The Sealed header (counter and tag) for this message.

Source

pub fn open( &mut self, sealed: &Sealed, buf: &mut [u8], aad: &[u8], ) -> Result<(), SessionError>

Opens a message from the peer, verifying it and decrypting buf in place.

The message is rejected if its counter has already been seen or is older than the replay window still tracks, and if its tag does not authenticate. On any rejection buf is left zeroed, so a failed open never yields readable bytes. The replay window only advances on a message that authenticates, so a forged counter cannot push genuine messages out of the window.

§Arguments
  • sealed - the counter and tag that arrived with the ciphertext.
  • buf - the ciphertext, replaced in place by the plaintext on success.
  • aad - the same associated data the sender authenticated.
§Returns

Ok(()) if the message is authentic and fresh, with buf now the plaintext.

§Errors

Returns SessionError::Replayed if the counter repeats or is too old, or SessionError::Inauthentic if the message fails authentication.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.