Skip to main content

PaseProver

Struct PaseProver 

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

Commissioner-side PASE state machine.

Drives the SPAKE2+ handshake from the commissioner’s (initiator’s) perspective. Sans-IO: the caller is responsible for transmitting and receiving bytes.

§Construction

§Driving the handshake

  1. Call start to get the first outbound message bytes.
  2. Feed inbound bytes into handle_pbkdf_response (negotiation path) or skip to step 3 (known-params path).
  3. Call next_message to get Pake1 bytes.
  4. Feed inbound Pake2 bytes into handle_pake2.
  5. Call next_message to get Pake3 bytes.
  6. After the peer confirms success, call finish to retrieve the PaseSessionKeys.

Use expected_inbound at any point to query which message type the machine is currently waiting for.

Implementations§

Source§

impl PaseProver

Source

pub fn new_with_negotiation(pin: u32, initiator_session_id: u16) -> Result<Self>

Construct a prover that negotiates PBKDF parameters (sends PBKDFParamRequest first).

initiator_session_id is the non-zero secured-session id this commissioner advertises for the peer to address us by. It is included in the PBKDFParamRequest wire message and hashed into the SPAKE2+ transcript, so it must be fixed before start is called.

Pre-samples the SPAKE2+ x scalar and the 32-byte initiator nonce so that start cannot fail due to randomness.

§Errors
Source

pub fn new_with_known_params( pin: u32, params: PasePbkdfParams, initiator_session_id: u16, ) -> Result<Self>

Construct a prover with PBKDF parameters already known (skips negotiation; first message is Pake1).

Validates params against Matter spec §3.10.3 bounds before accepting.

initiator_session_id is accepted for API symmetry with new_with_negotiation but is unused on this path: the known-params flow sends no PBKDFParamRequest, so the id never reaches the wire or the transcript, and responder_session_id will always be None. (Secured-session-id negotiation requires the negotiation path, which the commissioning driver uses.)

§Errors
Source

pub fn expected_inbound(&self) -> Option<PaseMessageKind>

Returns the message kind the state machine is currently waiting to receive, or None if the machine is in an outbound-only state (waiting to emit a message) or has completed / been poisoned.

Source

pub fn responder_session_id(&self) -> Option<u16>

The responder’s advertised secured-session id, captured from PBKDFParamResponse. None before Self::handle_pbkdf_response (and on the known-params path, which exchanges no PBKDF messages).

Source

pub fn start(&mut self) -> Result<Vec<u8>>

Produce the first outbound message.

  • Negotiation path: emits PBKDFParamRequest TLV bytes.
  • Known-params path: derives w0/w1, computes X, emits Pake1 TLV bytes.

May only be called once, from the initial state. Repeated calls or calls from any later state return Error::UnexpectedMessage.

§Errors
Source

pub fn handle_pbkdf_response(&mut self, bytes: &[u8]) -> Result<()>

Process an inbound PBKDFParamResponse message.

Decodes the response, validates the PBKDF parameters, and composes the transcript context as SHA-256(SPAKE_CONTEXT || pbkdfReq || pbkdfResp).

After this call, next_message emits Pake1.

§Errors
Source

pub fn handle_pake2(&mut self, bytes: &[u8]) -> Result<()>

Process an inbound Pake2 message.

Performs the SPAKE2+ cryptographic operations:

  1. Decode Y from the Pake2 TLV.
  2. Compute Z and V (the shared point values).
  3. Compute the transcript hash TT_HASH.
  4. Derive confirmation keys KcA, KcB.
  5. Verify the device’s confirmation tag cB in constant time via verify_tag (subtle CT-EQ, never ==).
  6. Compute our confirmation tag cA.
  7. Derive session keys.

After this call, next_message emits Pake3.

§Security

Tag comparison at step 5 MUST be constant-time. This is enforced by routing through verify_tag (in pase::spake2plus) which uses subtle::ConstantTimeEq.

§Errors
Source

pub fn next_message(&mut self) -> Result<Vec<u8>>

Produce the next outbound message.

§Errors
Source

pub fn finish(self) -> Result<PaseSessionKeys>

Finalise the session and retrieve the derived session keys.

May only be called after next_message has emitted Pake3 (i.e., the state machine is in the Complete state).

§Errors

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.