Botan 3.13.0
Crypto and TLS for C&
Botan::SPAKE2p::VerifierContext Class Referencefinal

#include <spake2p.h>

Public Member Functions

const SystemParametersparameters () const
std::vector< uint8_t > process_message (std::span< const uint8_t > peer_message, RandomNumberGenerator &rng)
secure_vector< uint8_t > shared_secret () const
void skip_confirmation ()
 VerifierContext (const SystemParameters &params, const RegistrationRecord &record, std::span< const uint8_t > prover_id, std::span< const uint8_t > verifier_id, std::span< const uint8_t > context={})
void verify_confirmation (std::span< const uint8_t > confirmation)

Detailed Description

SPAKE2+ (RFC 9383) Verifier

The verifier does not know the password itself; it stores only the registration record.

Definition at line 343 of file spake2p.h.

Constructor & Destructor Documentation

◆ VerifierContext()

Botan::SPAKE2p::VerifierContext::VerifierContext ( const SystemParameters & params,
const RegistrationRecord & record,
std::span< const uint8_t > prover_id,
std::span< const uint8_t > verifier_id,
std::span< const uint8_t > context = {} )

Set up for an execution of the protocol

The identities and context must be agreed upon by both parties; the identities must additionally match the values used during password registration. Both the identities and the context may be empty.

Definition at line 392 of file spake2p.cpp.

396 :
397 m_params(params),
398 m_record(record),
399 m_prover_id(prover_id.begin(), prover_id.end()),
400 m_verifier_id(verifier_id.begin(), verifier_id.end()),
401 m_context(context.begin(), context.end()) {}

Member Function Documentation

◆ parameters()

const SystemParameters & Botan::SPAKE2p::VerifierContext::parameters ( ) const
inline

Return the system parameters

Definition at line 407 of file spake2p.h.

407{ return m_params; }

◆ process_message()

std::vector< uint8_t > Botan::SPAKE2p::VerifierContext::process_message ( std::span< const uint8_t > peer_message,
RandomNumberGenerator & rng )

Consume the prover's key share (shareP) and return the verifier's response (shareV followed by confirmV), which is sent to the prover.

This can be called only once. Throws Decoding_Error if the key share is malformed.

Definition at line 403 of file spake2p.cpp.

404 {
405 BOTAN_STATE_CHECK(m_state == State::Initial);
406
407 const auto x = EC_AffinePoint::deserialize_uncompressed(m_params.group(), peer_message);
408 if(!x) {
409 throw Decoding_Error("Invalid SPAKE2+ key share");
410 }
411
412 const auto& w0 = m_record.m_w0;
413
414 const auto y = EC_Scalar::random(m_params.group(), rng);
415 const auto g = EC_AffinePoint::generator(m_params.group());
416
417 // RFC 9383 Section 3.3: Y = y*P + w0*N
418 const auto share_v_pt = EC_AffinePoint::mul_px_qy(g, y, m_params.spake2p_n(), w0, rng);
419 if(!share_v_pt) {
420 throw Internal_Error("Computed the identity element during SPAKE2+ key exchange");
421 }
422 const auto share_v = share_v_pt->serialize_uncompressed();
423
424 // RFC 9383 Section 3.3: Z = h*y*(X - w0*M), V = h*y*L
425 const auto z = EC_AffinePoint::mul_px_qy(*x, y, m_params.spake2p_m(), (y * w0).negate(), rng);
426 if(!z) {
427 throw Decoding_Error("Invalid SPAKE2+ key share");
428 }
429 const auto v = m_record.m_l.mul(y, rng);
430
431 auto keys = spake2p_key_schedule(m_params, m_context, m_prover_id, m_verifier_id, peer_message, share_v, *z, v, w0);
432
433 m_shared_secret = std::move(keys.shared_key);
434 m_expected_confirmation = std::move(keys.confirm_p);
435 m_state = State::Responded;
436
437 return concat<std::vector<uint8_t>>(share_v, keys.confirm_v);
438}
#define BOTAN_STATE_CHECK(expr)
Definition assert.h:49
static std::optional< EC_AffinePoint > deserialize_uncompressed(const EC_Group &group, std::span< const uint8_t > bytes)
static std::optional< EC_AffinePoint > mul_px_qy(const EC_AffinePoint &p, const EC_Scalar &x, const EC_AffinePoint &q, const EC_Scalar &y, RandomNumberGenerator &rng)
static EC_AffinePoint generator(const EC_Group &group)
Return the standard group generator.
Definition ec_apoint.cpp:84
static EC_Scalar random(const EC_Group &group, RandomNumberGenerator &rng)
Definition ec_scalar.cpp:64
constexpr auto concat(Rs &&... ranges)
Definition concat_util.h:90

References BOTAN_STATE_CHECK, Botan::concat(), Botan::EC_AffinePoint::deserialize_uncompressed(), Botan::EC_AffinePoint::generator(), Botan::EC_AffinePoint::mul_px_qy(), and Botan::EC_Scalar::random().

◆ shared_secret()

secure_vector< uint8_t > Botan::SPAKE2p::VerifierContext::shared_secret ( ) const

Return the shared secret (K_shared)

This may be called only after verify_confirmation has succeeded, or after skip_confirmation.

RFC 9383 Section 3.3: "The Verifier MUST NOT send application data to the Prover until it has received and verified the confirmation message."

Definition at line 461 of file spake2p.cpp.

461 {
462 BOTAN_STATE_CHECK(m_state == State::Complete);
463 return m_shared_secret;
464}

References BOTAN_STATE_CHECK.

◆ skip_confirmation()

void Botan::SPAKE2p::VerifierContext::skip_confirmation ( )

Skip checking the prover's key confirmation (confirmP)

This can be called after process_message, in place of verify_confirmation, to allow extracting the shared secret without having checked the prover's key confirmation.

Warning
After calling this, nothing is known about the peer; only a prover which knows the password can compute the same shared secret, but no evidence of this has been received. It is intended solely for protocols which embed SPAKE2+ and perform the prover's key confirmation themselves, for example the proposed TLS PAKE extension, where the TLS handshake takes the place of confirmP. Anywhere else, use verify_confirmation.

Definition at line 454 of file spake2p.cpp.

454 {
455 BOTAN_STATE_CHECK(m_state == State::Responded);
456
457 m_expected_confirmation.clear();
458 m_state = State::Complete;
459}

References BOTAN_STATE_CHECK.

◆ verify_confirmation()

void Botan::SPAKE2p::VerifierContext::verify_confirmation ( std::span< const uint8_t > confirmation)

Check the prover's key confirmation (confirmP)

Throws Invalid_Authentication_Tag if the confirmation is wrong, meaning the prover does not know the password.

Definition at line 440 of file spake2p.cpp.

440 {
441 BOTAN_STATE_CHECK(m_state == State::Responded);
442
443 if(!constant_time_compare(m_expected_confirmation, confirmation)) {
444 m_expected_confirmation.clear();
445 m_shared_secret.clear();
446 m_state = State::Failed;
447 throw Invalid_Authentication_Tag("SPAKE2+ key confirmation failed");
448 }
449
450 m_expected_confirmation.clear();
451 m_state = State::Complete;
452}
bool constant_time_compare(std::span< const uint8_t > x, std::span< const uint8_t > y)
Definition mem_ops.cpp:17

References BOTAN_STATE_CHECK, and Botan::constant_time_compare().


The documentation for this class was generated from the following files: