Simplifying error handling (#232)
This commit is contained in:
+19
-21
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ciphersuite::CipherSuite,
|
ciphersuite::CipherSuite,
|
||||||
errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
|
errors::{utils::check_slice_size, InternalError, ProtocolError},
|
||||||
group::Group,
|
group::Group,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
keypair::{KeyPair, PublicKey},
|
keypair::{KeyPair, PublicKey},
|
||||||
@@ -36,7 +36,7 @@ fn build_inner_envelope_internal<CS: CipherSuite>(
|
|||||||
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
||||||
let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
|
let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
|
||||||
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
|
let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
|
||||||
&CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash>(
|
&CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash>(
|
||||||
&keypair_seed[..],
|
&keypair_seed[..],
|
||||||
@@ -54,7 +54,7 @@ fn recover_keys_internal<CS: CipherSuite>(
|
|||||||
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
||||||
let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
|
let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
|
||||||
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
|
let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
|
||||||
&CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash>(
|
&CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash>(
|
||||||
&keypair_seed[..],
|
&keypair_seed[..],
|
||||||
@@ -73,11 +73,11 @@ pub(crate) enum InnerEnvelopeMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<u8> for InnerEnvelopeMode {
|
impl TryFrom<u8> for InnerEnvelopeMode {
|
||||||
type Error = PakeError;
|
type Error = ProtocolError;
|
||||||
fn try_from(x: u8) -> Result<Self, Self::Error> {
|
fn try_from(x: u8) -> Result<Self, Self::Error> {
|
||||||
match x {
|
match x {
|
||||||
1 => Ok(InnerEnvelopeMode::Internal),
|
1 => Ok(InnerEnvelopeMode::Internal),
|
||||||
_ => Err(PakeError::SerializationError),
|
_ => Err(ProtocolError::SerializationError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -170,15 +170,13 @@ impl<CS: CipherSuite> Envelope<CS> {
|
|||||||
let mode = InnerEnvelopeMode::Internal; // Better way to hard-code this?
|
let mode = InnerEnvelopeMode::Internal; // Better way to hard-code this?
|
||||||
|
|
||||||
if bytes.len() < NONCE_LEN {
|
if bytes.len() < NONCE_LEN {
|
||||||
return Err(ProtocolError::VerificationError(
|
return Err(ProtocolError::SerializationError);
|
||||||
PakeError::SerializationError,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
let nonce = bytes[..NONCE_LEN].to_vec();
|
let nonce = bytes[..NONCE_LEN].to_vec();
|
||||||
|
|
||||||
let remainder = match mode {
|
let remainder = match mode {
|
||||||
InnerEnvelopeMode::Zero => {
|
InnerEnvelopeMode::Zero => {
|
||||||
return Err(InternalPakeError::IncompatibleEnvelopeModeError.into())
|
return Err(InternalError::IncompatibleEnvelopeModeError.into())
|
||||||
}
|
}
|
||||||
InnerEnvelopeMode::Internal => bytes[NONCE_LEN..].to_vec(),
|
InnerEnvelopeMode::Internal => bytes[NONCE_LEN..].to_vec(),
|
||||||
};
|
};
|
||||||
@@ -242,18 +240,18 @@ impl<CS: CipherSuite> Envelope<CS> {
|
|||||||
nonce: &[u8],
|
nonce: &[u8],
|
||||||
aad: &[u8],
|
aad: &[u8],
|
||||||
mode: InnerEnvelopeMode,
|
mode: InnerEnvelopeMode,
|
||||||
) -> Result<SealRawResult<CS>, InternalPakeError> {
|
) -> Result<SealRawResult<CS>, InternalError> {
|
||||||
let h = Hkdf::<CS::Hash>::new(None, key);
|
let h = Hkdf::<CS::Hash>::new(None, key);
|
||||||
let mut hmac_key = vec![0u8; Self::hmac_key_size()];
|
let mut hmac_key = vec![0u8; Self::hmac_key_size()];
|
||||||
let mut export_key = vec![0u8; Self::export_key_size()];
|
let mut export_key = vec![0u8; Self::export_key_size()];
|
||||||
|
|
||||||
h.expand(&[nonce, STR_AUTH_KEY].concat(), &mut hmac_key)
|
h.expand(&[nonce, STR_AUTH_KEY].concat(), &mut hmac_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
h.expand(&[nonce, STR_EXPORT_KEY].concat(), &mut export_key)
|
h.expand(&[nonce, STR_EXPORT_KEY].concat(), &mut export_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
|
|
||||||
let mut hmac = Hmac::<CS::Hash>::new_from_slice(&hmac_key)
|
let mut hmac =
|
||||||
.map_err(|_| InternalPakeError::HmacError)?;
|
Hmac::<CS::Hash>::new_from_slice(&hmac_key).map_err(|_| InternalError::HmacError)?;
|
||||||
hmac.update(nonce);
|
hmac.update(nonce);
|
||||||
hmac.update(aad);
|
hmac.update(aad);
|
||||||
|
|
||||||
@@ -279,7 +277,7 @@ impl<CS: CipherSuite> Envelope<CS> {
|
|||||||
) -> Result<OpenedEnvelope<CS>, ProtocolError> {
|
) -> Result<OpenedEnvelope<CS>, ProtocolError> {
|
||||||
let client_static_keypair = match self.mode {
|
let client_static_keypair = match self.mode {
|
||||||
InnerEnvelopeMode::Zero => {
|
InnerEnvelopeMode::Zero => {
|
||||||
return Err(InternalPakeError::IncompatibleEnvelopeModeError.into())
|
return Err(InternalError::IncompatibleEnvelopeModeError.into())
|
||||||
}
|
}
|
||||||
InnerEnvelopeMode::Internal => recover_keys_internal::<CS>(key, &self.nonce)?,
|
InnerEnvelopeMode::Internal => recover_keys_internal::<CS>(key, &self.nonce)?,
|
||||||
};
|
};
|
||||||
@@ -307,22 +305,22 @@ impl<CS: CipherSuite> Envelope<CS> {
|
|||||||
&self,
|
&self,
|
||||||
key: &[u8],
|
key: &[u8],
|
||||||
aad: &[u8],
|
aad: &[u8],
|
||||||
) -> Result<OpenedInnerEnvelope<CS::Hash>, InternalPakeError> {
|
) -> Result<OpenedInnerEnvelope<CS::Hash>, InternalError> {
|
||||||
let h = Hkdf::<CS::Hash>::new(None, key);
|
let h = Hkdf::<CS::Hash>::new(None, key);
|
||||||
let mut hmac_key = vec![0u8; Self::hmac_key_size()];
|
let mut hmac_key = vec![0u8; Self::hmac_key_size()];
|
||||||
let mut export_key = vec![0u8; Self::export_key_size()];
|
let mut export_key = vec![0u8; Self::export_key_size()];
|
||||||
|
|
||||||
h.expand(&[&self.nonce, STR_AUTH_KEY].concat(), &mut hmac_key)
|
h.expand(&[&self.nonce, STR_AUTH_KEY].concat(), &mut hmac_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
h.expand(&[&self.nonce, STR_EXPORT_KEY].concat(), &mut export_key)
|
h.expand(&[&self.nonce, STR_EXPORT_KEY].concat(), &mut export_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
|
|
||||||
let mut hmac = Hmac::<CS::Hash>::new_from_slice(&hmac_key)
|
let mut hmac =
|
||||||
.map_err(|_| InternalPakeError::HmacError)?;
|
Hmac::<CS::Hash>::new_from_slice(&hmac_key).map_err(|_| InternalError::HmacError)?;
|
||||||
hmac.update(&self.nonce);
|
hmac.update(&self.nonce);
|
||||||
hmac.update(aad);
|
hmac.update(aad);
|
||||||
if hmac.verify(&self.hmac).is_err() {
|
if hmac.verify(&self.hmac).is_err() {
|
||||||
return Err(InternalPakeError::SealOpenHmacError);
|
return Err(InternalError::SealOpenHmacError);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(OpenedInnerEnvelope {
|
Ok(OpenedInnerEnvelope {
|
||||||
|
|||||||
+45
-170
@@ -13,7 +13,7 @@ use displaydoc::Display;
|
|||||||
|
|
||||||
/// Represents an error in the manipulation of internal cryptographic data
|
/// Represents an error in the manipulation of internal cryptographic data
|
||||||
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
||||||
pub enum InternalPakeError<T = Infallible> {
|
pub enum InternalError<T = Infallible> {
|
||||||
/// Custom [`SecretKey`](crate::keypair::SecretKey) error type
|
/// Custom [`SecretKey`](crate::keypair::SecretKey) error type
|
||||||
Custom(T),
|
Custom(T),
|
||||||
/// Deserializing from a byte sequence failed
|
/// Deserializing from a byte sequence failed
|
||||||
@@ -29,10 +29,6 @@ pub enum InternalPakeError<T = Infallible> {
|
|||||||
},
|
},
|
||||||
/// Could not decompress point.
|
/// Could not decompress point.
|
||||||
PointError,
|
PointError,
|
||||||
/// Key belongs to a small subgroup!
|
|
||||||
SubGroupError,
|
|
||||||
/// hashing to a key failed
|
|
||||||
HashingFailure,
|
|
||||||
/// Computing the hash-to-curve function failed
|
/// Computing the hash-to-curve function failed
|
||||||
HashToCurveError,
|
HashToCurveError,
|
||||||
/// Computing HKDF failed while deriving subkeys
|
/// Computing HKDF failed while deriving subkeys
|
||||||
@@ -41,27 +37,17 @@ pub enum InternalPakeError<T = Infallible> {
|
|||||||
HmacError,
|
HmacError,
|
||||||
/// Computing the slow hashing function failed
|
/// Computing the slow hashing function failed
|
||||||
SlowHashError,
|
SlowHashError,
|
||||||
/** This error occurs when the envelope seal fails
|
|
||||||
Constructing the envelope seal failed. */
|
|
||||||
SealError,
|
|
||||||
/** This error occurs when the envelope seal open fails
|
|
||||||
Opening the envelope seal failed. */
|
|
||||||
SealOpenError,
|
|
||||||
/** This error occurs when the envelope seal open hmac check fails
|
/** This error occurs when the envelope seal open hmac check fails
|
||||||
HMAC check in seal open failed. */
|
HMAC check in seal open failed. */
|
||||||
SealOpenHmacError,
|
SealOpenHmacError,
|
||||||
/** This error occurs when the envelope cannot be constructed properly
|
|
||||||
based on the credentials that were specified to be required. */
|
|
||||||
InvalidEnvelopeStructureError,
|
|
||||||
/** This error occurs when attempting to open an envelope of the wrong
|
/** This error occurs when attempting to open an envelope of the wrong
|
||||||
type (base mode, custom identifier) */
|
type (base mode, custom identifier) */
|
||||||
IncompatibleEnvelopeModeError,
|
IncompatibleEnvelopeModeError,
|
||||||
/** This error occurs when the envelope is opened and deserialization
|
/// This error occurs when the inner envelope is malformed
|
||||||
fails */
|
InvalidInnerEnvelopeError,
|
||||||
UnexpectedEnvelopeContentsError,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Debug> Debug for InternalPakeError<T> {
|
impl<T: Debug> Debug for InternalError<T> {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::Custom(custom) => f.debug_tuple("InvalidByteSequence").field(custom).finish(),
|
Self::Custom(custom) => f.debug_tuple("InvalidByteSequence").field(custom).finish(),
|
||||||
@@ -77,134 +63,45 @@ impl<T: Debug> Debug for InternalPakeError<T> {
|
|||||||
.field("actual_len", actual_len)
|
.field("actual_len", actual_len)
|
||||||
.finish(),
|
.finish(),
|
||||||
Self::PointError => f.debug_tuple("PointError").finish(),
|
Self::PointError => f.debug_tuple("PointError").finish(),
|
||||||
Self::SubGroupError => f.debug_tuple("SubGroupError").finish(),
|
|
||||||
Self::HashingFailure => f.debug_tuple("HashingFailure").finish(),
|
|
||||||
Self::HashToCurveError => f.debug_tuple("HashToCurveError").finish(),
|
Self::HashToCurveError => f.debug_tuple("HashToCurveError").finish(),
|
||||||
Self::HkdfError => f.debug_tuple("HkdfError").finish(),
|
Self::HkdfError => f.debug_tuple("HkdfError").finish(),
|
||||||
Self::HmacError => f.debug_tuple("HmacError").finish(),
|
Self::HmacError => f.debug_tuple("HmacError").finish(),
|
||||||
Self::SlowHashError => f.debug_tuple("SlowHashError").finish(),
|
Self::SlowHashError => f.debug_tuple("SlowHashError").finish(),
|
||||||
Self::SealError => f.debug_tuple("SealError").finish(),
|
|
||||||
Self::SealOpenError => f.debug_tuple("SealOpenError").finish(),
|
|
||||||
Self::SealOpenHmacError => f.debug_tuple("SealOpenHmacError").finish(),
|
Self::SealOpenHmacError => f.debug_tuple("SealOpenHmacError").finish(),
|
||||||
Self::InvalidEnvelopeStructureError => {
|
|
||||||
f.debug_tuple("InvalidEnvelopeStructureError").finish()
|
|
||||||
}
|
|
||||||
Self::IncompatibleEnvelopeModeError => {
|
Self::IncompatibleEnvelopeModeError => {
|
||||||
f.debug_tuple("IncompatibleEnvelopeModeError").finish()
|
f.debug_tuple("IncompatibleEnvelopeModeError").finish()
|
||||||
}
|
}
|
||||||
Self::UnexpectedEnvelopeContentsError => {
|
Self::InvalidInnerEnvelopeError => f.debug_tuple("InvalidInnerEnvelopeError").finish(),
|
||||||
f.debug_tuple("UnexpectedEnvelopeContentsError").finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<T: Error> Error for InternalPakeError<T> {}
|
impl<T: Error> Error for InternalError<T> {}
|
||||||
|
|
||||||
impl InternalPakeError {
|
impl InternalError {
|
||||||
/// Convert `InternalPakeError<Infallible>` into `InternalPakeError<T>
|
/// Convert `InternalError<Infallible>` into `InternalError<T>
|
||||||
pub fn into_custom<T>(self) -> InternalPakeError<T> {
|
pub fn into_custom<T>(self) -> InternalError<T> {
|
||||||
match self {
|
match self {
|
||||||
Self::Custom(_) => unreachable!(),
|
Self::Custom(_) => unreachable!(),
|
||||||
Self::InvalidByteSequence => InternalPakeError::InvalidByteSequence,
|
Self::InvalidByteSequence => InternalError::InvalidByteSequence,
|
||||||
Self::SizeError {
|
Self::SizeError {
|
||||||
name,
|
name,
|
||||||
len,
|
len,
|
||||||
actual_len,
|
actual_len,
|
||||||
} => InternalPakeError::SizeError {
|
} => InternalError::SizeError {
|
||||||
name,
|
name,
|
||||||
len,
|
len,
|
||||||
actual_len,
|
actual_len,
|
||||||
},
|
},
|
||||||
Self::PointError => InternalPakeError::PointError,
|
Self::PointError => InternalError::PointError,
|
||||||
Self::SubGroupError => InternalPakeError::SubGroupError,
|
Self::HashToCurveError => InternalError::HashToCurveError,
|
||||||
Self::HashingFailure => InternalPakeError::HashingFailure,
|
Self::HkdfError => InternalError::HkdfError,
|
||||||
Self::HashToCurveError => InternalPakeError::HashToCurveError,
|
Self::HmacError => InternalError::HmacError,
|
||||||
Self::HkdfError => InternalPakeError::HkdfError,
|
Self::SlowHashError => InternalError::SlowHashError,
|
||||||
Self::HmacError => InternalPakeError::HmacError,
|
Self::SealOpenHmacError => InternalError::SealOpenHmacError,
|
||||||
Self::SlowHashError => InternalPakeError::SlowHashError,
|
Self::IncompatibleEnvelopeModeError => InternalError::IncompatibleEnvelopeModeError,
|
||||||
Self::SealError => InternalPakeError::SealError,
|
Self::InvalidInnerEnvelopeError => InternalError::InvalidInnerEnvelopeError,
|
||||||
Self::SealOpenError => InternalPakeError::SealOpenError,
|
|
||||||
Self::SealOpenHmacError => InternalPakeError::SealOpenHmacError,
|
|
||||||
Self::InvalidEnvelopeStructureError => InternalPakeError::InvalidEnvelopeStructureError,
|
|
||||||
Self::IncompatibleEnvelopeModeError => InternalPakeError::IncompatibleEnvelopeModeError,
|
|
||||||
Self::UnexpectedEnvelopeContentsError => {
|
|
||||||
InternalPakeError::UnexpectedEnvelopeContentsError
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents an error in password checking
|
|
||||||
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
|
||||||
pub enum PakeError<T = Infallible> {
|
|
||||||
/** This error results from an internal error during PRF construction
|
|
||||||
|
|
||||||
Internal error during PRF verification: {0} */
|
|
||||||
CryptoError(InternalPakeError<T>),
|
|
||||||
/** This error occurs when the server object that is being called finish() on is malformed
|
|
||||||
Incomplete set of keys passed into finish() function */
|
|
||||||
IncompleteKeysError,
|
|
||||||
/// The provided server public key doesn't match the sealed one
|
|
||||||
IncompatibleServerStaticPublicKeyError,
|
|
||||||
/// Error in key exchange protocol when attempting to validate MACs
|
|
||||||
KeyExchangeMacValidationError,
|
|
||||||
/// Error in validating credentials
|
|
||||||
InvalidLoginError,
|
|
||||||
/// Error with serializing / deserializing protocol messages
|
|
||||||
SerializationError,
|
|
||||||
/// Identity group element was encountered during deserialization, which is invalid
|
|
||||||
IdentityGroupElementError,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Debug> Debug for PakeError<T> {
|
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
|
||||||
match self {
|
|
||||||
Self::CryptoError(internal_pake_error) => f
|
|
||||||
.debug_tuple("CryptoError")
|
|
||||||
.field(internal_pake_error)
|
|
||||||
.finish(),
|
|
||||||
Self::IncompleteKeysError => f.debug_tuple("IncompleteKeysError").finish(),
|
|
||||||
Self::IncompatibleServerStaticPublicKeyError => f
|
|
||||||
.debug_tuple("IncompatibleServerStaticPublicKeyError")
|
|
||||||
.finish(),
|
|
||||||
Self::KeyExchangeMacValidationError => {
|
|
||||||
f.debug_tuple("KeyExchangeMacValidationError").finish()
|
|
||||||
}
|
|
||||||
Self::InvalidLoginError => f.debug_tuple("InvalidLoginError").finish(),
|
|
||||||
Self::SerializationError => f.debug_tuple("SerializationError").finish(),
|
|
||||||
Self::IdentityGroupElementError => f.debug_tuple("IdentityGroupElementError").finish(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
impl<T: Error> Error for PakeError<T> {}
|
|
||||||
|
|
||||||
// This is meant to express future(ly) non-trivial ways of converting the
|
|
||||||
// internal error into a PakeError
|
|
||||||
impl<T> From<InternalPakeError<T>> for PakeError<T> {
|
|
||||||
fn from(e: InternalPakeError<T>) -> PakeError<T> {
|
|
||||||
PakeError::CryptoError(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PakeError {
|
|
||||||
/// Convert `PakeError<Infallible>` into `PakeError<T>
|
|
||||||
pub fn into_custom<T>(self) -> PakeError<T> {
|
|
||||||
match self {
|
|
||||||
Self::CryptoError(internal_pake_error) => {
|
|
||||||
PakeError::CryptoError(internal_pake_error.into_custom())
|
|
||||||
}
|
|
||||||
Self::IncompleteKeysError => PakeError::IncompleteKeysError,
|
|
||||||
Self::IncompatibleServerStaticPublicKeyError => {
|
|
||||||
PakeError::IncompatibleServerStaticPublicKeyError
|
|
||||||
}
|
|
||||||
Self::KeyExchangeMacValidationError => PakeError::KeyExchangeMacValidationError,
|
|
||||||
Self::InvalidLoginError => PakeError::InvalidLoginError,
|
|
||||||
Self::SerializationError => PakeError::SerializationError,
|
|
||||||
Self::IdentityGroupElementError => PakeError::IdentityGroupElementError,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,40 +109,29 @@ impl PakeError {
|
|||||||
/// Represents an error in protocol handling
|
/// Represents an error in protocol handling
|
||||||
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
#[derive(Clone, Display, Eq, Hash, PartialEq)]
|
||||||
pub enum ProtocolError<T = Infallible> {
|
pub enum ProtocolError<T = Infallible> {
|
||||||
/** This error results from an error during password verification
|
/// Internal error encountered
|
||||||
|
LibraryError(InternalError<T>),
|
||||||
Internal error during password verification: {0} */
|
/// Error in validating credentials
|
||||||
VerificationError(PakeError<T>),
|
InvalidLoginError,
|
||||||
/// This error occurs when the inner envelope is malformed
|
/// Error with serializing / deserializing protocol messages
|
||||||
InvalidInnerEnvelopeError,
|
SerializationError,
|
||||||
/** This error occurs when the server answer cannot be handled
|
|
||||||
Server response cannot be handled. */
|
|
||||||
ServerError,
|
|
||||||
/** This error occurs when the server specifies an envelope credentials
|
|
||||||
format that is invalid */
|
|
||||||
ServerInvalidEnvelopeCredentialsFormatError,
|
|
||||||
/** This error occurs when the client request cannot be handled
|
|
||||||
Client request cannot be handled. */
|
|
||||||
ClientError,
|
|
||||||
/** This error occurs when the client detects that the server has
|
/** This error occurs when the client detects that the server has
|
||||||
reflected the OPRF value (beta == alpha) */
|
reflected the OPRF value (beta == alpha) */
|
||||||
ReflectedValueError,
|
ReflectedValueError,
|
||||||
|
/// Identity group element was encountered during deserialization, which is invalid
|
||||||
|
IdentityGroupElementError,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Debug> Debug for ProtocolError<T> {
|
impl<T: Debug> Debug for ProtocolError<T> {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
Self::VerificationError(pake_error) => f
|
Self::LibraryError(pake_error) => {
|
||||||
.debug_tuple("VerificationError")
|
f.debug_tuple("LibraryError").field(pake_error).finish()
|
||||||
.field(pake_error)
|
}
|
||||||
.finish(),
|
Self::InvalidLoginError => f.debug_tuple("InvalidLoginError").finish(),
|
||||||
Self::InvalidInnerEnvelopeError => f.debug_tuple("InvalidInnerEnvelopeError").finish(),
|
Self::SerializationError => f.debug_tuple("SerializationError").finish(),
|
||||||
Self::ServerError => f.debug_tuple("ServerError").finish(),
|
|
||||||
Self::ServerInvalidEnvelopeCredentialsFormatError => f
|
|
||||||
.debug_tuple("ServerInvalidEnvelopeCredentialsFormatError")
|
|
||||||
.finish(),
|
|
||||||
Self::ClientError => f.debug_tuple("ClientError").finish(),
|
|
||||||
Self::ReflectedValueError => f.debug_tuple("ReflectedValueError").finish(),
|
Self::ReflectedValueError => f.debug_tuple("ReflectedValueError").finish(),
|
||||||
|
Self::IdentityGroupElementError => f.debug_tuple("IdentityGroupElementError").finish(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,19 +139,11 @@ impl<T: Debug> Debug for ProtocolError<T> {
|
|||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
impl<T: Error> Error for ProtocolError<T> {}
|
impl<T: Error> Error for ProtocolError<T> {}
|
||||||
|
|
||||||
// This is meant to express future(ly) non-trivial ways of converting the
|
|
||||||
// Pake error into a ProtocolError
|
|
||||||
impl<T> From<PakeError<T>> for ProtocolError<T> {
|
|
||||||
fn from(e: PakeError<T>) -> ProtocolError<T> {
|
|
||||||
ProtocolError::VerificationError(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is meant to express future(ly) non-trivial ways of converting the
|
// This is meant to express future(ly) non-trivial ways of converting the
|
||||||
// internal error into a ProtocolError
|
// internal error into a ProtocolError
|
||||||
impl<T> From<InternalPakeError<T>> for ProtocolError<T> {
|
impl<T> From<InternalError<T>> for ProtocolError<T> {
|
||||||
fn from(e: InternalPakeError<T>) -> ProtocolError<T> {
|
fn from(e: InternalError<T>) -> ProtocolError<T> {
|
||||||
ProtocolError::VerificationError(e.into())
|
Self::LibraryError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,16 +160,13 @@ impl ProtocolError {
|
|||||||
/// Convert `ProtocolError<Infallible>` into `ProtocolError<T>
|
/// Convert `ProtocolError<Infallible>` into `ProtocolError<T>
|
||||||
pub fn into_custom<T>(self) -> ProtocolError<T> {
|
pub fn into_custom<T>(self) -> ProtocolError<T> {
|
||||||
match self {
|
match self {
|
||||||
Self::VerificationError(pake_error) => {
|
Self::LibraryError(internal_error) => {
|
||||||
ProtocolError::VerificationError(pake_error.into_custom())
|
ProtocolError::LibraryError(internal_error.into_custom())
|
||||||
}
|
}
|
||||||
Self::InvalidInnerEnvelopeError => ProtocolError::InvalidInnerEnvelopeError,
|
Self::InvalidLoginError => ProtocolError::InvalidLoginError,
|
||||||
Self::ServerError => ProtocolError::ServerError,
|
Self::SerializationError => ProtocolError::SerializationError,
|
||||||
Self::ServerInvalidEnvelopeCredentialsFormatError => {
|
|
||||||
ProtocolError::ServerInvalidEnvelopeCredentialsFormatError
|
|
||||||
}
|
|
||||||
Self::ClientError => ProtocolError::ClientError,
|
|
||||||
Self::ReflectedValueError => ProtocolError::ReflectedValueError,
|
Self::ReflectedValueError => ProtocolError::ReflectedValueError,
|
||||||
|
Self::IdentityGroupElementError => ProtocolError::IdentityGroupElementError,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -303,9 +178,9 @@ pub(crate) mod utils {
|
|||||||
slice: &'a [u8],
|
slice: &'a [u8],
|
||||||
expected_len: usize,
|
expected_len: usize,
|
||||||
arg_name: &'static str,
|
arg_name: &'static str,
|
||||||
) -> Result<&'a [u8], InternalPakeError<T>> {
|
) -> Result<&'a [u8], InternalError<T>> {
|
||||||
if slice.len() != expected_len {
|
if slice.len() != expected_len {
|
||||||
return Err(InternalPakeError::SizeError {
|
return Err(InternalError::SizeError {
|
||||||
name: arg_name,
|
name: arg_name,
|
||||||
len: expected_len,
|
len: expected_len,
|
||||||
actual_len: slice.len(),
|
actual_len: slice.len(),
|
||||||
@@ -318,9 +193,9 @@ pub(crate) mod utils {
|
|||||||
slice: &'a [u8],
|
slice: &'a [u8],
|
||||||
expected_len: usize,
|
expected_len: usize,
|
||||||
arg_name: &'static str,
|
arg_name: &'static str,
|
||||||
) -> Result<&'a [u8], InternalPakeError> {
|
) -> Result<&'a [u8], InternalError> {
|
||||||
if slice.len() < expected_len {
|
if slice.len() < expected_len {
|
||||||
return Err(InternalPakeError::SizeError {
|
return Err(InternalError::SizeError {
|
||||||
name: arg_name,
|
name: arg_name,
|
||||||
len: expected_len,
|
len: expected_len,
|
||||||
actual_len: slice.len(),
|
actual_len: slice.len(),
|
||||||
|
|||||||
+4
-4
@@ -3,7 +3,7 @@
|
|||||||
// This source code is licensed under the MIT license found in the
|
// This source code is licensed under the MIT license found in the
|
||||||
// LICENSE file in the root directory of this source tree.
|
// LICENSE file in the root directory of this source tree.
|
||||||
|
|
||||||
use crate::errors::{InternalPakeError, ProtocolError};
|
use crate::errors::{InternalError, ProtocolError};
|
||||||
use crate::hash::Hash;
|
use crate::hash::Hash;
|
||||||
use crate::serialization::i2osp;
|
use crate::serialization::i2osp;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
@@ -16,9 +16,9 @@ fn div_ceil(x: usize, y: usize) -> usize {
|
|||||||
x / y + additive
|
x / y + additive
|
||||||
}
|
}
|
||||||
|
|
||||||
fn xor(x: &[u8], y: &[u8]) -> Result<Vec<u8>, InternalPakeError> {
|
fn xor(x: &[u8], y: &[u8]) -> Result<Vec<u8>, InternalError> {
|
||||||
if x.len() != y.len() {
|
if x.len() != y.len() {
|
||||||
return Err(InternalPakeError::HashToCurveError);
|
return Err(InternalError::HashToCurveError);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(x.iter().zip(y).map(|(&x1, &x2)| x1 ^ x2).collect())
|
Ok(x.iter().zip(y).map(|(&x1, &x2)| x1 ^ x2).collect())
|
||||||
@@ -36,7 +36,7 @@ pub fn expand_message_xmd<H: Hash>(
|
|||||||
|
|
||||||
let ell = div_ceil(len_in_bytes, b_in_bytes);
|
let ell = div_ceil(len_in_bytes, b_in_bytes);
|
||||||
if ell > 255 {
|
if ell > 255 {
|
||||||
return Err(InternalPakeError::HashToCurveError.into());
|
return Err(InternalError::HashToCurveError.into());
|
||||||
}
|
}
|
||||||
let dst_prime = [dst, &i2osp(dst.len(), 1)?].concat();
|
let dst_prime = [dst, &i2osp(dst.len(), 1)?].concat();
|
||||||
let z_pad = i2osp(0, r_in_bytes)?;
|
let z_pad = i2osp(0, r_in_bytes)?;
|
||||||
|
|||||||
+3
-3
@@ -12,7 +12,7 @@ pub(crate) mod p256;
|
|||||||
mod ristretto;
|
mod ristretto;
|
||||||
mod x25519;
|
mod x25519;
|
||||||
|
|
||||||
use crate::errors::{InternalPakeError, ProtocolError};
|
use crate::errors::{InternalError, ProtocolError};
|
||||||
use crate::hash::Hash;
|
use crate::hash::Hash;
|
||||||
use core::ops::Mul;
|
use core::ops::Mul;
|
||||||
use generic_array::{ArrayLength, GenericArray};
|
use generic_array::{ArrayLength, GenericArray};
|
||||||
@@ -47,7 +47,7 @@ pub trait Group: Copy + Sized + for<'a> Mul<&'a <Self as Group>::Scalar, Output
|
|||||||
/// Return a scalar from its fixed-length bytes representation
|
/// Return a scalar from its fixed-length bytes representation
|
||||||
fn from_scalar_slice(
|
fn from_scalar_slice(
|
||||||
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
||||||
) -> Result<Self::Scalar, InternalPakeError>;
|
) -> Result<Self::Scalar, InternalError>;
|
||||||
/// picks a scalar at random
|
/// picks a scalar at random
|
||||||
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar;
|
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar;
|
||||||
/// Serializes a scalar to bytes
|
/// Serializes a scalar to bytes
|
||||||
@@ -60,7 +60,7 @@ pub trait Group: Copy + Sized + for<'a> Mul<&'a <Self as Group>::Scalar, Output
|
|||||||
/// Return an element from its fixed-length bytes representation
|
/// Return an element from its fixed-length bytes representation
|
||||||
fn from_element_slice(
|
fn from_element_slice(
|
||||||
element_bits: &GenericArray<u8, Self::ElemLen>,
|
element_bits: &GenericArray<u8, Self::ElemLen>,
|
||||||
) -> Result<Self, InternalPakeError>;
|
) -> Result<Self, InternalError>;
|
||||||
/// Serializes the `self` group element
|
/// Serializes the `self` group element
|
||||||
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen>;
|
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen>;
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -9,7 +9,7 @@
|
|||||||
)]
|
)]
|
||||||
|
|
||||||
use super::Group;
|
use super::Group;
|
||||||
use crate::errors::{InternalPakeError, ProtocolError};
|
use crate::errors::{InternalError, ProtocolError};
|
||||||
use crate::hash::Hash;
|
use crate::hash::Hash;
|
||||||
use core::ops::{Add, Div, Mul, Neg, Sub};
|
use core::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
use core::str::FromStr;
|
use core::str::FromStr;
|
||||||
@@ -71,12 +71,12 @@ impl Group for ProjectivePoint {
|
|||||||
let p0 = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates(
|
let p0 = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates(
|
||||||
&q0x, &q0y, false,
|
&q0x, &q0y, false,
|
||||||
))
|
))
|
||||||
.ok_or(InternalPakeError::PointError)?
|
.ok_or(InternalError::PointError)?
|
||||||
.to_curve();
|
.to_curve();
|
||||||
let p1 = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates(
|
let p1 = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates(
|
||||||
&q1x, &q1y, false,
|
&q1x, &q1y, false,
|
||||||
))
|
))
|
||||||
.ok_or(InternalPakeError::PointError)?;
|
.ok_or(InternalError::PointError)?;
|
||||||
|
|
||||||
Ok(p0 + p1)
|
Ok(p0 + p1)
|
||||||
}
|
}
|
||||||
@@ -113,7 +113,7 @@ impl Group for ProjectivePoint {
|
|||||||
|
|
||||||
fn from_scalar_slice(
|
fn from_scalar_slice(
|
||||||
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
||||||
) -> Result<Self::Scalar, InternalPakeError> {
|
) -> Result<Self::Scalar, InternalError> {
|
||||||
Ok(Self::Scalar::from_bytes_reduced(scalar_bits))
|
Ok(Self::Scalar::from_bytes_reduced(scalar_bits))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,8 +131,8 @@ impl Group for ProjectivePoint {
|
|||||||
|
|
||||||
fn from_element_slice(
|
fn from_element_slice(
|
||||||
element_bits: &GenericArray<u8, Self::ElemLen>,
|
element_bits: &GenericArray<u8, Self::ElemLen>,
|
||||||
) -> Result<Self, InternalPakeError> {
|
) -> Result<Self, InternalError> {
|
||||||
Option::from(Self::from_bytes(element_bits)).ok_or(InternalPakeError::PointError)
|
Option::from(Self::from_bytes(element_bits)).ok_or(InternalError::PointError)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
|
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
// LICENSE file in the root directory of this source tree.
|
// LICENSE file in the root directory of this source tree.
|
||||||
|
|
||||||
use super::Group;
|
use super::Group;
|
||||||
use crate::errors::{InternalPakeError, ProtocolError};
|
use crate::errors::{InternalError, ProtocolError};
|
||||||
use crate::hash::Hash;
|
use crate::hash::Hash;
|
||||||
use core::convert::TryInto;
|
use core::convert::TryInto;
|
||||||
use curve25519_dalek::{
|
use curve25519_dalek::{
|
||||||
@@ -30,7 +30,7 @@ impl Group for RistrettoPoint {
|
|||||||
uniform_bytes
|
uniform_bytes
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| InternalPakeError::HashToCurveError)?,
|
.map_err(|_| InternalError::HashToCurveError)?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ impl Group for RistrettoPoint {
|
|||||||
uniform_bytes
|
uniform_bytes
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.try_into()
|
.try_into()
|
||||||
.map_err(|_| InternalPakeError::HashToCurveError)?,
|
.map_err(|_| InternalError::HashToCurveError)?,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ impl Group for RistrettoPoint {
|
|||||||
type ScalarLen = U32;
|
type ScalarLen = U32;
|
||||||
fn from_scalar_slice(
|
fn from_scalar_slice(
|
||||||
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
||||||
) -> Result<Self::Scalar, InternalPakeError> {
|
) -> Result<Self::Scalar, InternalError> {
|
||||||
Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
|
Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
|
||||||
}
|
}
|
||||||
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
|
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
|
||||||
@@ -89,10 +89,10 @@ impl Group for RistrettoPoint {
|
|||||||
type ElemLen = U32;
|
type ElemLen = U32;
|
||||||
fn from_element_slice(
|
fn from_element_slice(
|
||||||
element_bits: &GenericArray<u8, Self::ElemLen>,
|
element_bits: &GenericArray<u8, Self::ElemLen>,
|
||||||
) -> Result<Self, InternalPakeError> {
|
) -> Result<Self, InternalError> {
|
||||||
CompressedRistretto::from_slice(element_bits)
|
CompressedRistretto::from_slice(element_bits)
|
||||||
.decompress()
|
.decompress()
|
||||||
.ok_or(InternalPakeError::PointError)
|
.ok_or(InternalError::PointError)
|
||||||
}
|
}
|
||||||
// serialization of a group element
|
// serialization of a group element
|
||||||
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
|
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
|
||||||
|
|||||||
+6
-8
@@ -4,7 +4,7 @@
|
|||||||
// LICENSE file in the root directory of this source tree.
|
// LICENSE file in the root directory of this source tree.
|
||||||
|
|
||||||
use super::Group;
|
use super::Group;
|
||||||
use crate::errors::{InternalPakeError, ProtocolError};
|
use crate::errors::{InternalError, ProtocolError};
|
||||||
use crate::hash::Hash;
|
use crate::hash::Hash;
|
||||||
use curve25519_dalek::{constants::X25519_BASEPOINT, montgomery::MontgomeryPoint, scalar::Scalar};
|
use curve25519_dalek::{constants::X25519_BASEPOINT, montgomery::MontgomeryPoint, scalar::Scalar};
|
||||||
use generic_array::{typenum::U32, GenericArray};
|
use generic_array::{typenum::U32, GenericArray};
|
||||||
@@ -26,7 +26,7 @@ impl Group for MontgomeryPoint {
|
|||||||
type ScalarLen = U32;
|
type ScalarLen = U32;
|
||||||
fn from_scalar_slice(
|
fn from_scalar_slice(
|
||||||
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
||||||
) -> Result<Self::Scalar, InternalPakeError> {
|
) -> Result<Self::Scalar, InternalError> {
|
||||||
Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
|
Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
|
||||||
}
|
}
|
||||||
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
|
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
|
||||||
@@ -64,7 +64,7 @@ impl Group for MontgomeryPoint {
|
|||||||
type ElemLen = U32;
|
type ElemLen = U32;
|
||||||
fn from_element_slice(
|
fn from_element_slice(
|
||||||
element_bits: &GenericArray<u8, Self::ElemLen>,
|
element_bits: &GenericArray<u8, Self::ElemLen>,
|
||||||
) -> Result<Self, InternalPakeError> {
|
) -> Result<Self, InternalError> {
|
||||||
Ok(Self(*element_bits.as_ref()))
|
Ok(Self(*element_bits.as_ref()))
|
||||||
}
|
}
|
||||||
// serialization of a group element
|
// serialization of a group element
|
||||||
@@ -93,8 +93,8 @@ impl Group for MontgomeryPoint {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test() -> Result<(), ProtocolError> {
|
fn test() -> Result<(), ProtocolError> {
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::PakeError, key_exchange::tripledh::TripleDH, slow_hash::NoOpHash, CipherSuite,
|
key_exchange::tripledh::TripleDH, slow_hash::NoOpHash, CipherSuite, ClientLogin,
|
||||||
ClientLogin, ClientLoginFinishParameters, ClientLoginFinishResult, ClientLoginStartResult,
|
ClientLoginFinishParameters, ClientLoginFinishResult, ClientLoginStartResult,
|
||||||
ClientRegistration, ClientRegistrationFinishParameters, ClientRegistrationFinishResult,
|
ClientRegistration, ClientRegistrationFinishParameters, ClientRegistrationFinishResult,
|
||||||
ClientRegistrationStartResult, ServerLogin, ServerLoginStartParameters,
|
ClientRegistrationStartResult, ServerLogin, ServerLoginStartParameters,
|
||||||
ServerLoginStartResult, ServerRegistration, ServerSetup,
|
ServerLoginStartResult, ServerRegistration, ServerSetup,
|
||||||
@@ -173,9 +173,7 @@ fn test() -> Result<(), ProtocolError> {
|
|||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
client.finish(message, ClientLoginFinishParameters::Default),
|
client.finish(message, ClientLoginFinishParameters::Default),
|
||||||
Err(ProtocolError::VerificationError(
|
Err(ProtocolError::InvalidLoginError)
|
||||||
PakeError::InvalidLoginError
|
|
||||||
))
|
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ciphersuite::CipherSuite,
|
ciphersuite::CipherSuite,
|
||||||
errors::{PakeError, ProtocolError},
|
errors::ProtocolError,
|
||||||
group::Group,
|
group::Group,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
keypair::{PrivateKey, PublicKey, SecretKey},
|
keypair::{PrivateKey, PublicKey, SecretKey},
|
||||||
@@ -83,7 +83,7 @@ pub trait KeyExchange<D: Hash, G: Group> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait FromBytes: Sized {
|
pub trait FromBytes: Sized {
|
||||||
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError>;
|
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, ProtocolError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ToBytes {
|
pub trait ToBytes {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
ciphersuite::CipherSuite,
|
ciphersuite::CipherSuite,
|
||||||
errors::{
|
errors::{
|
||||||
utils::{check_slice_size, check_slice_size_atleast},
|
utils::{check_slice_size, check_slice_size_atleast},
|
||||||
InternalPakeError, PakeError, ProtocolError,
|
InternalError, ProtocolError,
|
||||||
},
|
},
|
||||||
group::Group,
|
group::Group,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
@@ -88,7 +88,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
|||||||
|
|
||||||
let mut transcript_hasher = D::new()
|
let mut transcript_hasher = D::new()
|
||||||
.chain(STR_RFC)
|
.chain(STR_RFC)
|
||||||
.chain(&serialize(&context, 2).map_err(PakeError::into_custom)?)
|
.chain(&serialize(&context, 2).map_err(ProtocolError::into_custom)?)
|
||||||
.chain(&id_u)
|
.chain(&id_u)
|
||||||
.chain(&serialized_credential_request[..])
|
.chain(&serialized_credential_request[..])
|
||||||
.chain(&id_s)
|
.chain(&id_s)
|
||||||
@@ -109,7 +109,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut mac_hasher =
|
let mut mac_hasher =
|
||||||
Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalPakeError::HmacError)?;
|
Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalError::HmacError)?;
|
||||||
mac_hasher.update(&transcript_hasher.clone().finalize());
|
mac_hasher.update(&transcript_hasher.clone().finalize());
|
||||||
let mac = mac_hasher.finalize().into_bytes();
|
let mac = mac_hasher.finalize().into_bytes();
|
||||||
|
|
||||||
@@ -167,19 +167,17 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut server_mac =
|
let mut server_mac =
|
||||||
Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalPakeError::HmacError)?;
|
Hmac::<D>::new_from_slice(&result.1).map_err(|_| InternalError::HmacError)?;
|
||||||
server_mac.update(&transcript_hasher.clone().finalize());
|
server_mac.update(&transcript_hasher.clone().finalize());
|
||||||
|
|
||||||
if server_mac.verify(&ke2_message.mac).is_err() {
|
if server_mac.verify(&ke2_message.mac).is_err() {
|
||||||
return Err(ProtocolError::VerificationError(
|
return Err(ProtocolError::InvalidLoginError);
|
||||||
PakeError::KeyExchangeMacValidationError,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transcript_hasher.update(ke2_message.mac.to_vec());
|
transcript_hasher.update(ke2_message.mac.to_vec());
|
||||||
|
|
||||||
let mut client_mac =
|
let mut client_mac =
|
||||||
Hmac::<D>::new_from_slice(&result.2).map_err(|_| InternalPakeError::HmacError)?;
|
Hmac::<D>::new_from_slice(&result.2).map_err(|_| InternalError::HmacError)?;
|
||||||
client_mac.update(&transcript_hasher.finalize());
|
client_mac.update(&transcript_hasher.finalize());
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
@@ -200,13 +198,11 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
|||||||
ke2_state: &Self::KE2State,
|
ke2_state: &Self::KE2State,
|
||||||
) -> Result<Vec<u8>, ProtocolError> {
|
) -> Result<Vec<u8>, ProtocolError> {
|
||||||
let mut client_mac =
|
let mut client_mac =
|
||||||
Hmac::<D>::new_from_slice(&ke2_state.km3).map_err(|_| InternalPakeError::HmacError)?;
|
Hmac::<D>::new_from_slice(&ke2_state.km3).map_err(|_| InternalError::HmacError)?;
|
||||||
client_mac.update(&ke2_state.hashed_transcript);
|
client_mac.update(&ke2_state.hashed_transcript);
|
||||||
|
|
||||||
if client_mac.verify(&ke3_message.mac).is_err() {
|
if client_mac.verify(&ke3_message.mac).is_err() {
|
||||||
return Err(ProtocolError::VerificationError(
|
return Err(ProtocolError::InvalidLoginError);
|
||||||
PakeError::KeyExchangeMacValidationError,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ke2_state.session_key.to_vec())
|
Ok(ke2_state.session_key.to_vec())
|
||||||
@@ -256,7 +252,7 @@ pub struct Ke1Message<G: Group> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<G: Group> FromBytes for Ke1State<G> {
|
impl<G: Group> FromBytes for Ke1State<G> {
|
||||||
fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, PakeError> {
|
fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let key_len = <G as Group>::ElemLen::USIZE;
|
let key_len = <G as Group>::ElemLen::USIZE;
|
||||||
|
|
||||||
let nonce_len = NonceLen::USIZE;
|
let nonce_len = NonceLen::USIZE;
|
||||||
@@ -293,7 +289,7 @@ impl<G: Group> ToBytes for Ke1Message<G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<G: Group> FromBytes for Ke1Message<G> {
|
impl<G: Group> FromBytes for Ke1Message<G> {
|
||||||
fn from_bytes<CS: CipherSuite>(ke1_message_bytes: &[u8]) -> Result<Self, PakeError> {
|
fn from_bytes<CS: CipherSuite>(ke1_message_bytes: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let nonce_len = NonceLen::USIZE;
|
let nonce_len = NonceLen::USIZE;
|
||||||
let checked_nonce = check_slice_size(
|
let checked_nonce = check_slice_size(
|
||||||
ke1_message_bytes,
|
ke1_message_bytes,
|
||||||
@@ -363,7 +359,7 @@ pub struct Ke2Message<G: Group, HashLen: ArrayLength<u8>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<HashLen: ArrayLength<u8>> FromBytes for Ke2State<HashLen> {
|
impl<HashLen: ArrayLength<u8>> FromBytes for Ke2State<HashLen> {
|
||||||
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError> {
|
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let hash_len = HashLen::USIZE;
|
let hash_len = HashLen::USIZE;
|
||||||
let checked_bytes = check_slice_size(input, 3 * hash_len, "ke2_state")?;
|
let checked_bytes = check_slice_size(input, 3 * hash_len, "ke2_state")?;
|
||||||
|
|
||||||
@@ -390,7 +386,7 @@ impl<G: Group, HashLen: ArrayLength<u8>> Ke2Message<G, HashLen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<G: Group, HashLen: ArrayLength<u8>> FromBytes for Ke2Message<G, HashLen> {
|
impl<G: Group, HashLen: ArrayLength<u8>> FromBytes for Ke2Message<G, HashLen> {
|
||||||
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError> {
|
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let key_len = <G as Group>::ElemLen::USIZE;
|
let key_len = <G as Group>::ElemLen::USIZE;
|
||||||
let nonce_len = NonceLen::USIZE;
|
let nonce_len = NonceLen::USIZE;
|
||||||
let checked_nonce = check_slice_size_atleast(input, nonce_len, "ke2_message nonce")?;
|
let checked_nonce = check_slice_size_atleast(input, nonce_len, "ke2_message nonce")?;
|
||||||
@@ -461,7 +457,7 @@ impl<HashLen: ArrayLength<u8>> ToBytes for Ke3Message<HashLen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<HashLen: ArrayLength<u8>> FromBytes for Ke3Message<HashLen> {
|
impl<HashLen: ArrayLength<u8>> FromBytes for Ke3Message<HashLen> {
|
||||||
fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, PakeError> {
|
fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let checked_bytes = check_slice_size(bytes, HashLen::USIZE, "ke3_message")?;
|
let checked_bytes = check_slice_size(bytes, HashLen::USIZE, "ke3_message")?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -481,11 +477,11 @@ fn derive_3dh_keys<D: Hash, G: Group, S: SecretKey<G>>(
|
|||||||
let ikm: Vec<u8> = [
|
let ikm: Vec<u8> = [
|
||||||
&dh.sk1
|
&dh.sk1
|
||||||
.diffie_hellman(dh.pk1)
|
.diffie_hellman(dh.pk1)
|
||||||
.map_err(InternalPakeError::into_custom)?[..],
|
.map_err(InternalError::into_custom)?[..],
|
||||||
&dh.sk2.diffie_hellman(dh.pk2)?[..],
|
&dh.sk2.diffie_hellman(dh.pk2)?[..],
|
||||||
&dh.sk3
|
&dh.sk3
|
||||||
.diffie_hellman(dh.pk3)
|
.diffie_hellman(dh.pk3)
|
||||||
.map_err(InternalPakeError::into_custom)?[..],
|
.map_err(InternalError::into_custom)?[..],
|
||||||
]
|
]
|
||||||
.concat();
|
.concat();
|
||||||
|
|
||||||
@@ -533,7 +529,7 @@ fn hkdf_expand_label<D: Hash>(
|
|||||||
context: &[u8],
|
context: &[u8],
|
||||||
length: usize,
|
length: usize,
|
||||||
) -> Result<Vec<u8>, ProtocolError> {
|
) -> Result<Vec<u8>, ProtocolError> {
|
||||||
let h = Hkdf::<D>::from_prk(secret).map_err(|_| InternalPakeError::HkdfError)?;
|
let h = Hkdf::<D>::from_prk(secret).map_err(|_| InternalError::HkdfError)?;
|
||||||
hkdf_expand_label_extracted(&h, label, context, length)
|
hkdf_expand_label_extracted(&h, label, context, length)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,7 +543,7 @@ fn hkdf_expand_label_extracted<D: Hash>(
|
|||||||
|
|
||||||
let mut hkdf_label: Vec<u8> = Vec::new();
|
let mut hkdf_label: Vec<u8> = Vec::new();
|
||||||
|
|
||||||
let length_u16: u16 = u16::try_from(length).map_err(|_| PakeError::SerializationError)?;
|
let length_u16: u16 = u16::try_from(length).map_err(|_| ProtocolError::SerializationError)?;
|
||||||
hkdf_label.extend_from_slice(&length_u16.to_be_bytes());
|
hkdf_label.extend_from_slice(&length_u16.to_be_bytes());
|
||||||
|
|
||||||
let mut opaque_label: Vec<u8> = Vec::new();
|
let mut opaque_label: Vec<u8> = Vec::new();
|
||||||
@@ -558,7 +554,7 @@ fn hkdf_expand_label_extracted<D: Hash>(
|
|||||||
hkdf_label.extend_from_slice(&serialize(context, 1)?);
|
hkdf_label.extend_from_slice(&serialize(context, 1)?);
|
||||||
|
|
||||||
hkdf.expand(&hkdf_label, &mut okm)
|
hkdf.expand(&hkdf_label, &mut okm)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
Ok(okm)
|
Ok(okm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-19
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
|
|
||||||
use crate::errors::{InternalPakeError, ProtocolError};
|
use crate::errors::{InternalError, ProtocolError};
|
||||||
use crate::group::Group;
|
use crate::group::Group;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
@@ -93,7 +93,7 @@ impl<G: Group, S: SecretKey<G>> KeyPair<G, S> {
|
|||||||
/// material provided through the network which fits the key
|
/// material provided through the network which fits the key
|
||||||
/// representation (i.e. can be mapped to a curve point), but presents
|
/// representation (i.e. can be mapped to a curve point), but presents
|
||||||
/// some risk - e.g. small subgroup check
|
/// some risk - e.g. small subgroup check
|
||||||
pub(crate) fn check_public_key(key: PublicKey<G>) -> Result<PublicKey<G>, InternalPakeError> {
|
pub(crate) fn check_public_key(key: PublicKey<G>) -> Result<PublicKey<G>, InternalError> {
|
||||||
G::from_element_slice(GenericArray::from_slice(&key.0)).map(|_| key)
|
G::from_element_slice(GenericArray::from_slice(&key.0)).map(|_| key)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,44 +256,44 @@ impl<G: Group> PrivateKey<G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert from slice
|
/// Convert from slice
|
||||||
pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
|
pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalError> {
|
||||||
if key_bytes.len() == G::ScalarLen::USIZE {
|
if key_bytes.len() == G::ScalarLen::USIZE {
|
||||||
Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
|
Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
|
||||||
} else {
|
} else {
|
||||||
Err(InternalPakeError::InvalidByteSequence)
|
Err(InternalError::InvalidByteSequence)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A trait specifying the requirements for a private key container
|
/// A trait specifying the requirements for a private key container
|
||||||
pub trait SecretKey<G: Group>: Clone + Sized + Zeroize {
|
pub trait SecretKey<G: Group>: Clone + Sized + Zeroize {
|
||||||
/// Custom error type that can be passed down to `InternalPakeError::Custom`
|
/// Custom error type that can be passed down to `InternalError::Custom`
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
/// Diffie-Hellman key exchange implementation
|
/// Diffie-Hellman key exchange implementation
|
||||||
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError<Self::Error>>;
|
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalError<Self::Error>>;
|
||||||
|
|
||||||
/// Returns public key from private key
|
/// Returns public key from private key
|
||||||
fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError<Self::Error>>;
|
fn public_key(&self) -> Result<PublicKey<G>, InternalError<Self::Error>>;
|
||||||
|
|
||||||
/// Serialization into bytes
|
/// Serialization into bytes
|
||||||
fn serialize(&self) -> Vec<u8>;
|
fn serialize(&self) -> Vec<u8>;
|
||||||
|
|
||||||
/// Deserialization from bytes
|
/// Deserialization from bytes
|
||||||
fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError<Self::Error>>;
|
fn deserialize(input: &[u8]) -> Result<Self, InternalError<Self::Error>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G: Group> SecretKey<G> for PrivateKey<G> {
|
impl<G: Group> SecretKey<G> for PrivateKey<G> {
|
||||||
type Error = core::convert::Infallible;
|
type Error = core::convert::Infallible;
|
||||||
|
|
||||||
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError> {
|
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalError> {
|
||||||
let pk_data = GenericArray::<u8, G::ElemLen>::from_slice(&pk.0[..]);
|
let pk_data = GenericArray::<u8, G::ElemLen>::from_slice(&pk.0[..]);
|
||||||
let point = G::from_element_slice(pk_data)?;
|
let point = G::from_element_slice(pk_data)?;
|
||||||
let secret_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
|
let secret_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
|
||||||
Ok(G::mult_by_slice(&point, secret_data).to_arr().to_vec())
|
Ok(G::mult_by_slice(&point, secret_data).to_arr().to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError> {
|
fn public_key(&self) -> Result<PublicKey<G>, InternalError> {
|
||||||
let bytes_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
|
let bytes_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
|
||||||
Ok(PublicKey(Key(G::base_point()
|
Ok(PublicKey(Key(G::base_point()
|
||||||
.mult_by_slice(bytes_data)
|
.mult_by_slice(bytes_data)
|
||||||
@@ -304,8 +304,8 @@ impl<G: Group> SecretKey<G> for PrivateKey<G> {
|
|||||||
self.to_vec()
|
self.to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError> {
|
fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
|
||||||
PrivateKey::from_bytes(input).map_err(InternalPakeError::from)
|
PrivateKey::from_bytes(input).map_err(InternalError::from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,11 +351,11 @@ impl<G: Group> PublicKey<G> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Convert from slice
|
/// Convert from slice
|
||||||
pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalPakeError> {
|
pub fn from_bytes(key_bytes: &[u8]) -> Result<Self, InternalError> {
|
||||||
if key_bytes.len() == G::ElemLen::USIZE {
|
if key_bytes.len() == G::ElemLen::USIZE {
|
||||||
Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
|
Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
|
||||||
} else {
|
} else {
|
||||||
Err(InternalPakeError::InvalidByteSequence)
|
Err(InternalError::InvalidByteSequence)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,13 +471,11 @@ mod tests {
|
|||||||
fn diffie_hellman(
|
fn diffie_hellman(
|
||||||
&self,
|
&self,
|
||||||
pk: PublicKey<RistrettoPoint>,
|
pk: PublicKey<RistrettoPoint>,
|
||||||
) -> Result<Vec<u8>, InternalPakeError<Self::Error>> {
|
) -> Result<Vec<u8>, InternalError<Self::Error>> {
|
||||||
self.0.diffie_hellman(pk)
|
self.0.diffie_hellman(pk)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn public_key(
|
fn public_key(&self) -> Result<PublicKey<RistrettoPoint>, InternalError<Self::Error>> {
|
||||||
&self,
|
|
||||||
) -> Result<PublicKey<RistrettoPoint>, InternalPakeError<Self::Error>> {
|
|
||||||
self.0.public_key()
|
self.0.public_key()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,7 +483,7 @@ mod tests {
|
|||||||
self.0.serialize()
|
self.0.serialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError<Self::Error>> {
|
fn deserialize(input: &[u8]) -> Result<Self, InternalError<Self::Error>> {
|
||||||
PrivateKey::deserialize(input).map(Self)
|
PrivateKey::deserialize(input).map(Self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -748,7 +748,7 @@
|
|||||||
//! ```
|
//! ```
|
||||||
//! # use curve25519_dalek::ristretto::RistrettoPoint;
|
//! # use curve25519_dalek::ristretto::RistrettoPoint;
|
||||||
//! # use generic_array::{GenericArray, typenum::U32};
|
//! # use generic_array::{GenericArray, typenum::U32};
|
||||||
//! # use opaque_ke::{CipherSuite, errors::{InternalPakeError}, keypair::{KeyPair, PrivateKey, PublicKey, SecretKey}, ServerSetup};
|
//! # use opaque_ke::{CipherSuite, errors::{InternalError}, keypair::{KeyPair, PrivateKey, PublicKey, SecretKey}, ServerSetup};
|
||||||
//! # use rand::rngs::OsRng;
|
//! # use rand::rngs::OsRng;
|
||||||
//! # use zeroize::Zeroize;
|
//! # use zeroize::Zeroize;
|
||||||
//! # struct Default;
|
//! # struct Default;
|
||||||
@@ -773,14 +773,14 @@
|
|||||||
//! fn diffie_hellman(
|
//! fn diffie_hellman(
|
||||||
//! &self,
|
//! &self,
|
||||||
//! pk: PublicKey<RistrettoPoint>,
|
//! pk: PublicKey<RistrettoPoint>,
|
||||||
//! ) -> Result<Vec<u8>, InternalPakeError<Self::Error>> {
|
//! ) -> Result<Vec<u8>, InternalError<Self::Error>> {
|
||||||
//! YourRemoteKey::diffie_hellman(self, &pk.to_arr()).map_err(InternalPakeError::Custom)
|
//! YourRemoteKey::diffie_hellman(self, &pk.to_arr()).map_err(InternalError::Custom)
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! fn public_key(
|
//! fn public_key(
|
||||||
//! &self
|
//! &self
|
||||||
//! ) -> Result<PublicKey<RistrettoPoint>, InternalPakeError<Self::Error>> {
|
//! ) -> Result<PublicKey<RistrettoPoint>, InternalError<Self::Error>> {
|
||||||
//! YourRemoteKey::public_key(self).map(PublicKey::from_arr).map_err(InternalPakeError::Custom)
|
//! YourRemoteKey::public_key(self).map(PublicKey::from_arr).map_err(InternalError::Custom)
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! fn serialize(&self) -> Vec<u8> {
|
//! fn serialize(&self) -> Vec<u8> {
|
||||||
@@ -788,7 +788,7 @@
|
|||||||
//! todo!()
|
//! todo!()
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError<Self::Error>> {
|
//! fn deserialize(input: &[u8]) -> Result<Self, InternalError<Self::Error>> {
|
||||||
//! // if you use serde and the "serialize" crate feature, you won't need this
|
//! // if you use serde and the "serialize" crate feature, you won't need this
|
||||||
//! todo!()
|
//! todo!()
|
||||||
//! }
|
//! }
|
||||||
|
|||||||
+5
-5
@@ -10,7 +10,7 @@ use crate::{
|
|||||||
envelope::Envelope,
|
envelope::Envelope,
|
||||||
errors::{
|
errors::{
|
||||||
utils::{check_slice_size, check_slice_size_atleast},
|
utils::{check_slice_size, check_slice_size_atleast},
|
||||||
PakeError, ProtocolError,
|
ProtocolError,
|
||||||
},
|
},
|
||||||
group::Group,
|
group::Group,
|
||||||
key_exchange::traits::{FromBytes, KeyExchange, ToBytes},
|
key_exchange::traits::{FromBytes, KeyExchange, ToBytes},
|
||||||
@@ -65,7 +65,7 @@ impl<CS: CipherSuite> RegistrationRequest<CS> {
|
|||||||
|
|
||||||
// Throw an error if the identity group element is encountered
|
// Throw an error if the identity group element is encountered
|
||||||
if alpha.is_identity() {
|
if alpha.is_identity() {
|
||||||
return Err(PakeError::IdentityGroupElementError.into());
|
return Err(ProtocolError::IdentityGroupElementError);
|
||||||
}
|
}
|
||||||
Ok(Self { alpha })
|
Ok(Self { alpha })
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ impl<CS: CipherSuite> RegistrationResponse<CS> {
|
|||||||
|
|
||||||
// Throw an error if the identity group element is encountered
|
// Throw an error if the identity group element is encountered
|
||||||
if beta.is_identity() {
|
if beta.is_identity() {
|
||||||
return Err(PakeError::IdentityGroupElementError.into());
|
return Err(ProtocolError::IdentityGroupElementError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that public key is valid
|
// Ensure that public key is valid
|
||||||
@@ -255,7 +255,7 @@ impl<CS: CipherSuite> CredentialRequest<CS> {
|
|||||||
|
|
||||||
// Throw an error if the identity group element is encountered
|
// Throw an error if the identity group element is encountered
|
||||||
if alpha.is_identity() {
|
if alpha.is_identity() {
|
||||||
return Err(PakeError::IdentityGroupElementError.into());
|
return Err(ProtocolError::IdentityGroupElementError);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ke1_message =
|
let ke1_message =
|
||||||
@@ -347,7 +347,7 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
|
|||||||
|
|
||||||
// Throw an error if the identity group element is encountered
|
// Throw an error if the identity group element is encountered
|
||||||
if beta.is_identity() {
|
if beta.is_identity() {
|
||||||
return Err(PakeError::IdentityGroupElementError.into());
|
return Err(ProtocolError::IdentityGroupElementError);
|
||||||
}
|
}
|
||||||
|
|
||||||
let masking_nonce = checked_slice[elem_len..elem_len + nonce_len].to_vec();
|
let masking_nonce = checked_slice[elem_len..elem_len + nonce_len].to_vec();
|
||||||
|
|||||||
+17
-26
@@ -8,7 +8,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ciphersuite::CipherSuite,
|
ciphersuite::CipherSuite,
|
||||||
envelope::Envelope,
|
envelope::Envelope,
|
||||||
errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
|
errors::{utils::check_slice_size, InternalError, ProtocolError},
|
||||||
group::Group,
|
group::Group,
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
key_exchange::traits::{FromBytes, KeyExchange, ToBytesWithPointers},
|
key_exchange::traits::{FromBytes, KeyExchange, ToBytesWithPointers},
|
||||||
@@ -152,7 +152,7 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
|
|||||||
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
|
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
|
||||||
let min_expected_len = elem_len + scalar_len;
|
let min_expected_len = elem_len + scalar_len;
|
||||||
let checked_slice = (if input.len() <= min_expected_len {
|
let checked_slice = (if input.len() <= min_expected_len {
|
||||||
Err(InternalPakeError::SizeError {
|
Err(InternalError::SizeError {
|
||||||
name: "client_registration_bytes",
|
name: "client_registration_bytes",
|
||||||
len: min_expected_len,
|
len: min_expected_len,
|
||||||
actual_len: input.len(),
|
actual_len: input.len(),
|
||||||
@@ -333,7 +333,7 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
|
|||||||
let (randomized_pwd, h) = Hkdf::<CS::Hash>::extract(None, &password_derived_key);
|
let (randomized_pwd, h) = Hkdf::<CS::Hash>::extract(None, &password_derived_key);
|
||||||
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
|
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
|
||||||
h.expand(STR_MASKING_KEY, &mut masking_key)
|
h.expand(STR_MASKING_KEY, &mut masking_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
|
|
||||||
let result =
|
let result =
|
||||||
Envelope::<CS>::seal(rng, &password_derived_key, &r2.server_s_pk, optional_ids)?;
|
Envelope::<CS>::seal(rng, &password_derived_key, &r2.server_s_pk, optional_ids)?;
|
||||||
@@ -491,7 +491,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
|||||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
|
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
|
||||||
let checked_slice = (if input.len() <= scalar_len {
|
let checked_slice = (if input.len() <= scalar_len {
|
||||||
Err(InternalPakeError::SizeError {
|
Err(InternalError::SizeError {
|
||||||
name: "client_login_bytes",
|
name: "client_login_bytes",
|
||||||
len: scalar_len,
|
len: scalar_len,
|
||||||
actual_len: input.len(),
|
actual_len: input.len(),
|
||||||
@@ -665,7 +665,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
|||||||
let h = Hkdf::<CS::Hash>::new(None, &password_derived_key);
|
let h = Hkdf::<CS::Hash>::new(None, &password_derived_key);
|
||||||
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
|
let mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
|
||||||
h.expand(STR_MASKING_KEY, &mut masking_key)
|
h.expand(STR_MASKING_KEY, &mut masking_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
|
|
||||||
let (server_s_pk, envelope) = unmask_response::<CS>(
|
let (server_s_pk, envelope) = unmask_response::<CS>(
|
||||||
&masking_key,
|
&masking_key,
|
||||||
@@ -673,10 +673,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
|||||||
&credential_response.masked_response,
|
&credential_response.masked_response,
|
||||||
)
|
)
|
||||||
.map_err(|e| match e {
|
.map_err(|e| match e {
|
||||||
ProtocolError::InvalidInnerEnvelopeError => PakeError::InvalidLoginError.into(),
|
ProtocolError::SerializationError => ProtocolError::InvalidLoginError,
|
||||||
ProtocolError::VerificationError(PakeError::SerializationError) => {
|
|
||||||
PakeError::InvalidLoginError.into()
|
|
||||||
}
|
|
||||||
err => err,
|
err => err,
|
||||||
})?;
|
})?;
|
||||||
let server_s_pk_bytes = server_s_pk.to_arr().to_vec();
|
let server_s_pk_bytes = server_s_pk.to_arr().to_vec();
|
||||||
@@ -684,9 +681,9 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
|||||||
let opened_envelope = &envelope
|
let opened_envelope = &envelope
|
||||||
.open(&password_derived_key, &server_s_pk_bytes, &optional_ids)
|
.open(&password_derived_key, &server_s_pk_bytes, &optional_ids)
|
||||||
.map_err(|e| match e {
|
.map_err(|e| match e {
|
||||||
ProtocolError::VerificationError(PakeError::CryptoError(
|
ProtocolError::LibraryError(InternalError::SealOpenHmacError) => {
|
||||||
InternalPakeError::SealOpenHmacError,
|
ProtocolError::InvalidLoginError
|
||||||
)) => ProtocolError::VerificationError(PakeError::InvalidLoginError),
|
}
|
||||||
err => err,
|
err => err,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@@ -930,13 +927,7 @@ impl<CS: CipherSuite> ServerLogin<CS> {
|
|||||||
let session_key = <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::finish_ke(
|
let session_key = <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::finish_ke(
|
||||||
message.ke3_message,
|
message.ke3_message,
|
||||||
&self.ke2_state,
|
&self.ke2_state,
|
||||||
)
|
)?;
|
||||||
.map_err(|e| match e {
|
|
||||||
ProtocolError::VerificationError(PakeError::KeyExchangeMacValidationError) => {
|
|
||||||
ProtocolError::VerificationError(PakeError::InvalidLoginError)
|
|
||||||
}
|
|
||||||
err => err,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(ServerLoginFinishResult {
|
Ok(ServerLoginFinishResult {
|
||||||
session_key,
|
session_key,
|
||||||
@@ -1030,9 +1021,9 @@ fn oprf_key_from_seed<G: Group, D: Hash>(
|
|||||||
) -> Result<G::Scalar, ProtocolError> {
|
) -> Result<G::Scalar, ProtocolError> {
|
||||||
let mut ikm = vec![0u8; G::ScalarLen::USIZE];
|
let mut ikm = vec![0u8; G::ScalarLen::USIZE];
|
||||||
Hkdf::<D>::from_prk(oprf_seed)
|
Hkdf::<D>::from_prk(oprf_seed)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?
|
.map_err(|_| InternalError::HkdfError)?
|
||||||
.expand(&[credential_identifier, STR_OPRF_KEY].concat(), &mut ikm)
|
.expand(&[credential_identifier, STR_OPRF_KEY].concat(), &mut ikm)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
G::hash_to_scalar::<D>(&ikm[..], STR_OPAQUE_DERIVE_KEY_PAIR)
|
G::hash_to_scalar::<D>(&ikm[..], STR_OPAQUE_DERIVE_KEY_PAIR)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1044,12 +1035,12 @@ fn mask_response<CS: CipherSuite>(
|
|||||||
) -> Result<Vec<u8>, ProtocolError> {
|
) -> Result<Vec<u8>, ProtocolError> {
|
||||||
let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
|
let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
|
||||||
Hkdf::<CS::Hash>::from_prk(masking_key)
|
Hkdf::<CS::Hash>::from_prk(masking_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?
|
.map_err(|_| InternalError::HkdfError)?
|
||||||
.expand(
|
.expand(
|
||||||
&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD].concat(),
|
&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD].concat(),
|
||||||
&mut xor_pad,
|
&mut xor_pad,
|
||||||
)
|
)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
|
|
||||||
let plaintext = [&server_s_pk.to_arr()[..], &envelope.serialize()].concat();
|
let plaintext = [&server_s_pk.to_arr()[..], &envelope.serialize()].concat();
|
||||||
|
|
||||||
@@ -1067,12 +1058,12 @@ fn unmask_response<CS: CipherSuite>(
|
|||||||
) -> Result<(PublicKey<CS::KeGroup>, Envelope<CS>), ProtocolError> {
|
) -> Result<(PublicKey<CS::KeGroup>, Envelope<CS>), ProtocolError> {
|
||||||
let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
|
let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
|
||||||
Hkdf::<CS::Hash>::from_prk(masking_key)
|
Hkdf::<CS::Hash>::from_prk(masking_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?
|
.map_err(|_| InternalError::HkdfError)?
|
||||||
.expand(
|
.expand(
|
||||||
&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD].concat(),
|
&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD].concat(),
|
||||||
&mut xor_pad,
|
&mut xor_pad,
|
||||||
)
|
)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalError::HkdfError)?;
|
||||||
let plaintext: Vec<u8> = xor_pad
|
let plaintext: Vec<u8> = xor_pad
|
||||||
.iter()
|
.iter()
|
||||||
.zip(masked_response.iter())
|
.zip(masked_response.iter())
|
||||||
@@ -1084,7 +1075,7 @@ fn unmask_response<CS: CipherSuite>(
|
|||||||
|
|
||||||
// Ensure that public key is valid
|
// Ensure that public key is valid
|
||||||
let server_s_pk = KeyPair::<CS::KeGroup>::check_public_key(unchecked_server_s_pk)
|
let server_s_pk = KeyPair::<CS::KeGroup>::check_public_key(unchecked_server_s_pk)
|
||||||
.map_err(|_| ProtocolError::VerificationError(PakeError::SerializationError))?;
|
.map_err(|_| ProtocolError::SerializationError)?;
|
||||||
|
|
||||||
Ok((server_s_pk, envelope))
|
Ok((server_s_pk, envelope))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
// This source code is licensed under the MIT license found in the
|
// This source code is licensed under the MIT license found in the
|
||||||
// LICENSE file in the root directory of this source tree.
|
// LICENSE file in the root directory of this source tree.
|
||||||
|
|
||||||
use crate::errors::PakeError;
|
use crate::errors::ProtocolError;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
|
|
||||||
// Corresponds to the I2OSP() function from RFC8017
|
// Corresponds to the I2OSP() function from RFC8017
|
||||||
pub(crate) fn i2osp(input: usize, length: usize) -> Result<alloc::vec::Vec<u8>, PakeError> {
|
pub(crate) fn i2osp(input: usize, length: usize) -> Result<alloc::vec::Vec<u8>, ProtocolError> {
|
||||||
let sizeof_usize = core::mem::size_of::<usize>();
|
let sizeof_usize = core::mem::size_of::<usize>();
|
||||||
|
|
||||||
// Check if input >= 256^length
|
// Check if input >= 256^length
|
||||||
if (sizeof_usize as u32 - input.leading_zeros() / 8) > length as u32 {
|
if (sizeof_usize as u32 - input.leading_zeros() / 8) > length as u32 {
|
||||||
return Err(PakeError::SerializationError);
|
return Err(ProtocolError::SerializationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
if length <= sizeof_usize {
|
if length <= sizeof_usize {
|
||||||
@@ -28,9 +28,9 @@ pub(crate) fn i2osp(input: usize, length: usize) -> Result<alloc::vec::Vec<u8>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Corresponds to the OS2IP() function from RFC8017
|
// Corresponds to the OS2IP() function from RFC8017
|
||||||
pub(crate) fn os2ip(input: &[u8]) -> Result<usize, PakeError> {
|
pub(crate) fn os2ip(input: &[u8]) -> Result<usize, ProtocolError> {
|
||||||
if input.len() > core::mem::size_of::<usize>() {
|
if input.len() > core::mem::size_of::<usize>() {
|
||||||
return Err(PakeError::SerializationError);
|
return Err(ProtocolError::SerializationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut output_array = [0u8; core::mem::size_of::<usize>()];
|
let mut output_array = [0u8; core::mem::size_of::<usize>()];
|
||||||
@@ -39,20 +39,23 @@ pub(crate) fn os2ip(input: &[u8]) -> Result<usize, PakeError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Computes I2OSP(len(input), max_bytes) || input
|
// Computes I2OSP(len(input), max_bytes) || input
|
||||||
pub(crate) fn serialize(input: &[u8], max_bytes: usize) -> Result<Vec<u8>, PakeError> {
|
pub(crate) fn serialize(input: &[u8], max_bytes: usize) -> Result<Vec<u8>, ProtocolError> {
|
||||||
Ok([&i2osp(input.len(), max_bytes)?, input].concat())
|
Ok([&i2osp(input.len(), max_bytes)?, input].concat())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tokenizes an input of the format I2OSP(len(input), max_bytes) || input, outputting
|
// Tokenizes an input of the format I2OSP(len(input), max_bytes) || input, outputting
|
||||||
// (input, remainder)
|
// (input, remainder)
|
||||||
pub(crate) fn tokenize(input: &[u8], size_bytes: usize) -> Result<(Vec<u8>, Vec<u8>), PakeError> {
|
pub(crate) fn tokenize(
|
||||||
|
input: &[u8],
|
||||||
|
size_bytes: usize,
|
||||||
|
) -> Result<(Vec<u8>, Vec<u8>), ProtocolError> {
|
||||||
if size_bytes > core::mem::size_of::<usize>() || input.len() < size_bytes {
|
if size_bytes > core::mem::size_of::<usize>() || input.len() < size_bytes {
|
||||||
return Err(PakeError::SerializationError);
|
return Err(ProtocolError::SerializationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
let size = os2ip(&input[..size_bytes])?;
|
let size = os2ip(&input[..size_bytes])?;
|
||||||
if size_bytes + size > input.len() {
|
if size_bytes + size > input.len() {
|
||||||
return Err(PakeError::SerializationError);
|
return Err(ProtocolError::SerializationError);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ fn registration_request_roundtrip() {
|
|||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
match RegistrationRequest::<Default>::deserialize(identity_bytes.as_slice()) {
|
match RegistrationRequest::<Default>::deserialize(identity_bytes.as_slice()) {
|
||||||
Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
|
Err(ProtocolError::IdentityGroupElementError) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -140,7 +140,7 @@ fn registration_response_roundtrip() {
|
|||||||
assert!(match RegistrationResponse::<Default>::deserialize(
|
assert!(match RegistrationResponse::<Default>::deserialize(
|
||||||
&[identity_bytes, pubkey_bytes.to_vec()].concat()
|
&[identity_bytes, pubkey_bytes.to_vec()].concat()
|
||||||
) {
|
) {
|
||||||
Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
|
Err(ProtocolError::IdentityGroupElementError) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -201,7 +201,7 @@ fn credential_request_roundtrip() {
|
|||||||
assert!(match CredentialRequest::<Default>::deserialize(
|
assert!(match CredentialRequest::<Default>::deserialize(
|
||||||
&[identity_bytes, ke1m.to_vec()].concat()
|
&[identity_bytes, ke1m.to_vec()].concat()
|
||||||
) {
|
) {
|
||||||
Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
|
Err(ProtocolError::IdentityGroupElementError) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -251,7 +251,7 @@ fn credential_response_roundtrip() {
|
|||||||
]
|
]
|
||||||
.concat()
|
.concat()
|
||||||
) {
|
) {
|
||||||
Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
|
Err(ProtocolError::IdentityGroupElementError) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-11
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
//! Trait specifying a slow hashing function
|
//! Trait specifying a slow hashing function
|
||||||
|
|
||||||
use crate::{errors::InternalPakeError, hash::Hash};
|
use crate::{errors::InternalError, hash::Hash};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use digest::Digest;
|
use digest::Digest;
|
||||||
#[cfg(feature = "slow-hash")]
|
#[cfg(feature = "slow-hash")]
|
||||||
@@ -15,27 +15,21 @@ use generic_array::GenericArray;
|
|||||||
/// Used for the slow hashing function in OPAQUE
|
/// Used for the slow hashing function in OPAQUE
|
||||||
pub trait SlowHash<D: Hash> {
|
pub trait SlowHash<D: Hash> {
|
||||||
/// Computes the slow hashing function
|
/// Computes the slow hashing function
|
||||||
fn hash(
|
fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError>;
|
||||||
input: GenericArray<u8, <D as Digest>::OutputSize>,
|
|
||||||
) -> Result<Vec<u8>, InternalPakeError>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A no-op hash which simply returns its input
|
/// A no-op hash which simply returns its input
|
||||||
pub struct NoOpHash;
|
pub struct NoOpHash;
|
||||||
|
|
||||||
impl<D: Hash> SlowHash<D> for NoOpHash {
|
impl<D: Hash> SlowHash<D> for NoOpHash {
|
||||||
fn hash(
|
fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError> {
|
||||||
input: GenericArray<u8, <D as Digest>::OutputSize>,
|
|
||||||
) -> Result<Vec<u8>, InternalPakeError> {
|
|
||||||
Ok(input.to_vec())
|
Ok(input.to_vec())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "slow-hash")]
|
#[cfg(feature = "slow-hash")]
|
||||||
impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
|
impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
|
||||||
fn hash(
|
fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError> {
|
||||||
input: GenericArray<u8, <D as Digest>::OutputSize>,
|
|
||||||
) -> Result<Vec<u8>, InternalPakeError> {
|
|
||||||
let params = argon2::Argon2::default();
|
let params = argon2::Argon2::default();
|
||||||
let mut output = alloc::vec![0u8; <D as Digest>::OutputSize::USIZE];
|
let mut output = alloc::vec![0u8; <D as Digest>::OutputSize::USIZE];
|
||||||
params
|
params
|
||||||
@@ -46,7 +40,7 @@ impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
|
|||||||
&[],
|
&[],
|
||||||
&mut output,
|
&mut output,
|
||||||
)
|
)
|
||||||
.map_err(|_| InternalPakeError::SlowHashError)?;
|
.map_err(|_| InternalError::SlowHashError)?;
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -763,7 +763,7 @@ fn test_complete_flow(
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
assert!(match client_login_result {
|
assert!(match client_login_result {
|
||||||
Err(ProtocolError::VerificationError(PakeError::InvalidLoginError)) => true,
|
Err(ProtocolError::InvalidLoginError) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ fn test_blind<G: Group, H: Hash>(tvs: &[&str]) -> Result<(), ProtocolError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tests sksm, blinded_element -> evaluation_element
|
// Tests sksm, blinded_element -> evaluation_element
|
||||||
fn test_evaluate<G: Group>(tvs: &[&str]) -> Result<(), PakeError> {
|
fn test_evaluate<G: Group>(tvs: &[&str]) -> Result<(), ProtocolError> {
|
||||||
for tv in tvs {
|
for tv in tvs {
|
||||||
let parameters = populate_test_vectors(&serde_json::from_str(tv).unwrap());
|
let parameters = populate_test_vectors(&serde_json::from_str(tv).unwrap());
|
||||||
let evaluation_element = oprf::evaluate::<G>(
|
let evaluation_element = oprf::evaluate::<G>(
|
||||||
|
|||||||
Reference in New Issue
Block a user