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
PaseProver::new_with_negotiation— sendsPBKDFParamRequestfirst (the normal path when PBKDF params are not cached).PaseProver::new_with_known_params— skips negotiation; first message is Pake1 (when PBKDF params are already known from a prior session).
§Driving the handshake
- Call
startto get the first outbound message bytes. - Feed inbound bytes into
handle_pbkdf_response(negotiation path) or skip to step 3 (known-params path). - Call
next_messageto get Pake1 bytes. - Feed inbound Pake2 bytes into
handle_pake2. - Call
next_messageto get Pake3 bytes. - After the peer confirms success, call
finishto retrieve thePaseSessionKeys.
Use expected_inbound at any point to query
which message type the machine is currently waiting for.
Implementations§
Source§impl PaseProver
impl PaseProver
Sourcepub fn new_with_negotiation(pin: u32, initiator_session_id: u16) -> Result<Self>
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
Error::InvalidScalarif the CSPRNG is broken and a non-zero scalar cannot be sampled after 16 attempts (practically impossible).Error::PinDerivationFailedif the nonce fill fails.
Sourcepub fn new_with_known_params(
pin: u32,
params: PasePbkdfParams,
initiator_session_id: u16,
) -> Result<Self>
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
Error::PbkdfIterationsTooLowifparams.iterations < 1000.Error::PbkdfSaltLengthInvalidifparams.salt.len()∉ [16, 32].Error::InvalidScalarif the CSPRNG is broken.
Sourcepub fn expected_inbound(&self) -> Option<PaseMessageKind>
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.
Sourcepub fn responder_session_id(&self) -> Option<u16>
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).
Sourcepub fn start(&mut self) -> Result<Vec<u8>>
pub fn start(&mut self) -> Result<Vec<u8>>
Produce the first outbound message.
- Negotiation path: emits
PBKDFParamRequestTLV 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
Error::UnexpectedMessageif called from the wrong state.Error::Codecon TLV encoding failure.Error::PinDerivationFailed/Error::PbkdfIterationsTooLow/Error::PbkdfSaltLengthInvalidon KDF failure (known-params path).
Sourcepub fn handle_pbkdf_response(&mut self, bytes: &[u8]) -> Result<()>
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
Error::UnexpectedMessageif called from the wrong state.Error::InvalidParameterif the response is malformed or missing the requiredpbkdf_parametersfield.Error::PbkdfIterationsTooLow/Error::PbkdfIterationsTooHigh/Error::PbkdfSaltLengthInvalidif the responder’s parameters are out of spec. The too-high case caps a peer-supplied iteration count to prevent a commissioner CPU denial-of-service.Error::Codecon TLV decoding failure.
Sourcepub fn handle_pake2(&mut self, bytes: &[u8]) -> Result<()>
pub fn handle_pake2(&mut self, bytes: &[u8]) -> Result<()>
Process an inbound Pake2 message.
Performs the SPAKE2+ cryptographic operations:
- Decode Y from the Pake2 TLV.
- Compute Z and V (the shared point values).
- Compute the transcript hash
TT_HASH. - Derive confirmation keys
KcA,KcB. - Verify the device’s confirmation tag
cBin constant time viaverify_tag(subtle CT-EQ, never==). - Compute our confirmation tag
cA. - 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
Error::UnexpectedMessageif called from the wrong state.Error::InvalidParameterif Y is not a valid P-256 point.Error::ConfirmationTagMismatchif the device’scBtag fails constant-time verification (wrong PIN or compromised peer).Error::Codecon TLV decoding failure.Error::PinDerivationFailedon HKDF failure.
Sourcepub fn next_message(&mut self) -> Result<Vec<u8>>
pub fn next_message(&mut self) -> Result<Vec<u8>>
Produce the next outbound message.
- After
handle_pbkdf_response: emits Pake1. - After
handle_pake2: emits Pake3.
§Errors
Error::UnexpectedMessageif called from the wrong state.Error::Codecon TLV encoding failure.Error::PinDerivationFailed/Error::PbkdfIterationsTooLow/Error::PbkdfSaltLengthInvalidon KDF failure (Pake1 path only).
Sourcepub fn finish(self) -> Result<PaseSessionKeys>
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
Error::HandshakeIncompleteif called before the handshake has completed all phases.