pub(crate) mod kdf;
pub(crate) mod messages;
pub(crate) mod prover;
pub(crate) mod spake2plus;
pub(crate) mod verifier;
pub use kdf::pake_passcode_verifier;
pub use prover::PaseProver;
pub use verifier::PaseVerifier;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[non_exhaustive]
pub enum PaseMessageKind {
PbkdfParamRequest,
PbkdfParamResponse,
Pake1,
Pake2,
Pake3,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PasePbkdfParams {
pub iterations: u32,
pub salt: Vec<u8>,
}
#[derive(Clone, zeroize::ZeroizeOnDrop)]
pub struct PaseSessionKeys {
pub ke: [u8; 16],
pub i2r_key: [u8; 16],
pub r2i_key: [u8; 16],
pub attestation_key: [u8; 16],
}
impl core::fmt::Debug for PaseSessionKeys {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("PaseSessionKeys").finish_non_exhaustive()
}
}
#[cfg(test)]
mod secret_hygiene_tests {
use super::*;
fn assert_zeroize_on_drop<T: zeroize::ZeroizeOnDrop>() {}
#[test]
fn pase_session_keys_is_zeroize_on_drop() {
assert_zeroize_on_drop::<PaseSessionKeys>();
}
#[test]
fn pase_session_keys_debug_redacts_key_bytes() {
let keys = PaseSessionKeys {
ke: [0xAA; 16],
i2r_key: [0xBB; 16],
r2i_key: [0xCC; 16],
attestation_key: [0xDD; 16],
};
let s = format!("{keys:?}");
assert!(!s.contains("aa"), "ke bytes leaked: {s}");
assert!(!s.contains("bb"), "i2r_key bytes leaked: {s}");
assert!(!s.contains("cc"), "r2i_key bytes leaked: {s}");
assert!(!s.contains("dd"), "attestation_key bytes leaked: {s}");
assert!(s.contains("PaseSessionKeys"));
}
}