Skip to main content

PaseVerifier

Struct PaseVerifier 

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

Device-side PASE state machine.

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

§Construction

§Driving the handshake

  1. Feed the inbound PBKDFParamRequest bytes into handle_pbkdf_request (negotiation path), or skip to step 3 (known-params path).
  2. Call next_message to emit PBKDFParamResponse.
  3. Feed the inbound Pake1 bytes into handle_pake1.
  4. Call next_message to emit Pake2.
  5. Feed the inbound Pake3 bytes into handle_pake3.
  6. 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 PaseVerifier

Source

pub fn new( w0: [u8; 32], l: [u8; 65], params: PasePbkdfParams, responder_session_id: u16, ) -> Result<Self>

Production constructor: device stores pre-computed verification values.

In production the PIN is hashed to w0 and L once at provisioning time and the raw PIN is discarded. Pass those stored values here.

Validates params against Matter spec §3.10.3 bounds before accepting.

§Parameters
  • w0: 32-byte big-endian P-256 scalar derived from the PIN.
  • l: 65-byte uncompressed P-256 point L = w1·P.
  • params: PBKDF2 parameters used when w0/L were derived.
  • responder_session_id: the non-zero secured-session id this device advertises (in PBKDFParamResponse) for the peer to address it by.
§Errors
Source

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

Test/convenience constructor: derive w0 and L from the PIN.

In production a device never stores the PIN after provisioning — it stores w0 and L instead. This constructor is provided for tests and development use where deriving from a PIN is convenient.

§Parameters
  • responder_session_id: the non-zero secured-session id this device advertises (in PBKDFParamResponse) for the peer to address it by.
§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 or completed state.

Useful for routing inbound messages in a dispatcher.

Source

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

Process an inbound PBKDFParamRequest message (negotiation path).

Decodes the request, captures the raw bytes for transcript composition, and transitions to ReadyToSendPbkdfResponse. After this call, next_message emits PBKDFParamResponse.

§Errors
Source

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

Process an inbound Pake1 message.

Valid in two states:

  • AwaitingFirstMessage — commissioner skipped param negotiation (known-params path); context = SHA-256(SPAKE_CONTEXT).
  • AwaitingPake1 — negotiation complete; context already computed.

After this call, next_message emits Pake2.

§Cryptography
  1. Decode X from Pake1 TLV.
  2. Compute Y = y·P + w0·N (verifier’s SPAKE2+ share).
  3. Compute Z = y·(X − w0·M) and V = y·L (shared secrets).
  4. Compute the SPAKE2+ transcript hash TT_HASH.
  5. Split Ka (first 16 bytes) and Ke (last 16 bytes) from TT_HASH.
  6. Derive confirmation keys KcA/KcB from Ka.
  7. Compute cB = HMAC-SHA256(KcB, X) (our confirmation tag to send).
  8. Compute cA_expected = HMAC-SHA256(KcA, Y) (to verify in Pake3).
  9. Derive session keys from Ke.
§Errors
Source

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

Process an inbound Pake3 message.

Verifies the commissioner’s confirmation tag cA using constant-time comparison (subtle::ConstantTimeEq). If verification succeeds the state machine transitions to Complete and finish may be called.

§Security

Tag comparison 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.

Calling from any other state returns Error::UnexpectedMessage.

§Errors
Source

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

Finalise the session and retrieve the derived session keys.

May only be called after handle_pake3 has successfully verified cA (i.e., the state machine is in Complete).

§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.