Simplifying error handling (#232)

This commit is contained in:
Kevin Lewi
2021-08-22 12:28:19 -07:00
committed by GitHub
parent a99a934ead
commit aee4b5d50e
18 changed files with 177 additions and 324 deletions
+19 -21
View File
@@ -5,7 +5,7 @@
use crate::{
ciphersuite::CipherSuite,
errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
errors::{utils::check_slice_size, InternalError, ProtocolError},
group::Group,
hash::Hash,
keypair::{KeyPair, PublicKey},
@@ -36,7 +36,7 @@ fn build_inner_envelope_internal<CS: CipherSuite>(
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
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(
&CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash>(
&keypair_seed[..],
@@ -54,7 +54,7 @@ fn recover_keys_internal<CS: CipherSuite>(
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
let mut keypair_seed = vec![0u8; <CS::KeGroup as Group>::ScalarLen::USIZE];
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(
&CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash>(
&keypair_seed[..],
@@ -73,11 +73,11 @@ pub(crate) enum InnerEnvelopeMode {
}
impl TryFrom<u8> for InnerEnvelopeMode {
type Error = PakeError;
type Error = ProtocolError;
fn try_from(x: u8) -> Result<Self, Self::Error> {
match x {
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?
if bytes.len() < NONCE_LEN {
return Err(ProtocolError::VerificationError(
PakeError::SerializationError,
));
return Err(ProtocolError::SerializationError);
}
let nonce = bytes[..NONCE_LEN].to_vec();
let remainder = match mode {
InnerEnvelopeMode::Zero => {
return Err(InternalPakeError::IncompatibleEnvelopeModeError.into())
return Err(InternalError::IncompatibleEnvelopeModeError.into())
}
InnerEnvelopeMode::Internal => bytes[NONCE_LEN..].to_vec(),
};
@@ -242,18 +240,18 @@ impl<CS: CipherSuite> Envelope<CS> {
nonce: &[u8],
aad: &[u8],
mode: InnerEnvelopeMode,
) -> Result<SealRawResult<CS>, InternalPakeError> {
) -> Result<SealRawResult<CS>, InternalError> {
let h = Hkdf::<CS::Hash>::new(None, key);
let mut hmac_key = vec![0u8; Self::hmac_key_size()];
let mut export_key = vec![0u8; Self::export_key_size()];
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)
.map_err(|_| InternalPakeError::HkdfError)?;
.map_err(|_| InternalError::HkdfError)?;
let mut hmac = Hmac::<CS::Hash>::new_from_slice(&hmac_key)
.map_err(|_| InternalPakeError::HmacError)?;
let mut hmac =
Hmac::<CS::Hash>::new_from_slice(&hmac_key).map_err(|_| InternalError::HmacError)?;
hmac.update(nonce);
hmac.update(aad);
@@ -279,7 +277,7 @@ impl<CS: CipherSuite> Envelope<CS> {
) -> Result<OpenedEnvelope<CS>, ProtocolError> {
let client_static_keypair = match self.mode {
InnerEnvelopeMode::Zero => {
return Err(InternalPakeError::IncompatibleEnvelopeModeError.into())
return Err(InternalError::IncompatibleEnvelopeModeError.into())
}
InnerEnvelopeMode::Internal => recover_keys_internal::<CS>(key, &self.nonce)?,
};
@@ -307,22 +305,22 @@ impl<CS: CipherSuite> Envelope<CS> {
&self,
key: &[u8],
aad: &[u8],
) -> Result<OpenedInnerEnvelope<CS::Hash>, InternalPakeError> {
) -> Result<OpenedInnerEnvelope<CS::Hash>, InternalError> {
let h = Hkdf::<CS::Hash>::new(None, key);
let mut hmac_key = vec![0u8; Self::hmac_key_size()];
let mut export_key = vec![0u8; Self::export_key_size()];
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)
.map_err(|_| InternalPakeError::HkdfError)?;
.map_err(|_| InternalError::HkdfError)?;
let mut hmac = Hmac::<CS::Hash>::new_from_slice(&hmac_key)
.map_err(|_| InternalPakeError::HmacError)?;
let mut hmac =
Hmac::<CS::Hash>::new_from_slice(&hmac_key).map_err(|_| InternalError::HmacError)?;
hmac.update(&self.nonce);
hmac.update(aad);
if hmac.verify(&self.hmac).is_err() {
return Err(InternalPakeError::SealOpenHmacError);
return Err(InternalError::SealOpenHmacError);
}
Ok(OpenedInnerEnvelope {
+45 -170
View File
@@ -13,7 +13,7 @@ use displaydoc::Display;
/// Represents an error in the manipulation of internal cryptographic data
#[derive(Clone, Display, Eq, Hash, PartialEq)]
pub enum InternalPakeError<T = Infallible> {
pub enum InternalError<T = Infallible> {
/// Custom [`SecretKey`](crate::keypair::SecretKey) error type
Custom(T),
/// Deserializing from a byte sequence failed
@@ -29,10 +29,6 @@ pub enum InternalPakeError<T = Infallible> {
},
/// Could not decompress point.
PointError,
/// Key belongs to a small subgroup!
SubGroupError,
/// hashing to a key failed
HashingFailure,
/// Computing the hash-to-curve function failed
HashToCurveError,
/// Computing HKDF failed while deriving subkeys
@@ -41,27 +37,17 @@ pub enum InternalPakeError<T = Infallible> {
HmacError,
/// Computing the slow hashing function failed
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
HMAC check in seal open failed. */
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
type (base mode, custom identifier) */
IncompatibleEnvelopeModeError,
/** This error occurs when the envelope is opened and deserialization
fails */
UnexpectedEnvelopeContentsError,
/// This error occurs when the inner envelope is malformed
InvalidInnerEnvelopeError,
}
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 {
match self {
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)
.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::HkdfError => f.debug_tuple("HkdfError").finish(),
Self::HmacError => f.debug_tuple("HmacError").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::InvalidEnvelopeStructureError => {
f.debug_tuple("InvalidEnvelopeStructureError").finish()
}
Self::IncompatibleEnvelopeModeError => {
f.debug_tuple("IncompatibleEnvelopeModeError").finish()
}
Self::UnexpectedEnvelopeContentsError => {
f.debug_tuple("UnexpectedEnvelopeContentsError").finish()
}
Self::InvalidInnerEnvelopeError => f.debug_tuple("InvalidInnerEnvelopeError").finish(),
}
}
}
#[cfg(feature = "std")]
impl<T: Error> Error for InternalPakeError<T> {}
impl<T: Error> Error for InternalError<T> {}
impl InternalPakeError {
/// Convert `InternalPakeError<Infallible>` into `InternalPakeError<T>
pub fn into_custom<T>(self) -> InternalPakeError<T> {
impl InternalError {
/// Convert `InternalError<Infallible>` into `InternalError<T>
pub fn into_custom<T>(self) -> InternalError<T> {
match self {
Self::Custom(_) => unreachable!(),
Self::InvalidByteSequence => InternalPakeError::InvalidByteSequence,
Self::InvalidByteSequence => InternalError::InvalidByteSequence,
Self::SizeError {
name,
len,
actual_len,
} => InternalPakeError::SizeError {
} => InternalError::SizeError {
name,
len,
actual_len,
},
Self::PointError => InternalPakeError::PointError,
Self::SubGroupError => InternalPakeError::SubGroupError,
Self::HashingFailure => InternalPakeError::HashingFailure,
Self::HashToCurveError => InternalPakeError::HashToCurveError,
Self::HkdfError => InternalPakeError::HkdfError,
Self::HmacError => InternalPakeError::HmacError,
Self::SlowHashError => InternalPakeError::SlowHashError,
Self::SealError => InternalPakeError::SealError,
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,
Self::PointError => InternalError::PointError,
Self::HashToCurveError => InternalError::HashToCurveError,
Self::HkdfError => InternalError::HkdfError,
Self::HmacError => InternalError::HmacError,
Self::SlowHashError => InternalError::SlowHashError,
Self::SealOpenHmacError => InternalError::SealOpenHmacError,
Self::IncompatibleEnvelopeModeError => InternalError::IncompatibleEnvelopeModeError,
Self::InvalidInnerEnvelopeError => InternalError::InvalidInnerEnvelopeError,
}
}
}
@@ -212,40 +109,29 @@ impl PakeError {
/// Represents an error in protocol handling
#[derive(Clone, Display, Eq, Hash, PartialEq)]
pub enum ProtocolError<T = Infallible> {
/** This error results from an error during password verification
Internal error during password verification: {0} */
VerificationError(PakeError<T>),
/// This error occurs when the inner envelope is malformed
InvalidInnerEnvelopeError,
/** 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,
/// Internal error encountered
LibraryError(InternalError<T>),
/// Error in validating credentials
InvalidLoginError,
/// Error with serializing / deserializing protocol messages
SerializationError,
/** This error occurs when the client detects that the server has
reflected the OPRF value (beta == alpha) */
ReflectedValueError,
/// Identity group element was encountered during deserialization, which is invalid
IdentityGroupElementError,
}
impl<T: Debug> Debug for ProtocolError<T> {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::VerificationError(pake_error) => f
.debug_tuple("VerificationError")
.field(pake_error)
.finish(),
Self::InvalidInnerEnvelopeError => f.debug_tuple("InvalidInnerEnvelopeError").finish(),
Self::ServerError => f.debug_tuple("ServerError").finish(),
Self::ServerInvalidEnvelopeCredentialsFormatError => f
.debug_tuple("ServerInvalidEnvelopeCredentialsFormatError")
.finish(),
Self::ClientError => f.debug_tuple("ClientError").finish(),
Self::LibraryError(pake_error) => {
f.debug_tuple("LibraryError").field(pake_error).finish()
}
Self::InvalidLoginError => f.debug_tuple("InvalidLoginError").finish(),
Self::SerializationError => f.debug_tuple("SerializationError").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")]
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
// internal error into a ProtocolError
impl<T> From<InternalPakeError<T>> for ProtocolError<T> {
fn from(e: InternalPakeError<T>) -> ProtocolError<T> {
ProtocolError::VerificationError(e.into())
impl<T> From<InternalError<T>> for ProtocolError<T> {
fn from(e: InternalError<T>) -> ProtocolError<T> {
Self::LibraryError(e)
}
}
@@ -282,16 +160,13 @@ impl ProtocolError {
/// Convert `ProtocolError<Infallible>` into `ProtocolError<T>
pub fn into_custom<T>(self) -> ProtocolError<T> {
match self {
Self::VerificationError(pake_error) => {
ProtocolError::VerificationError(pake_error.into_custom())
Self::LibraryError(internal_error) => {
ProtocolError::LibraryError(internal_error.into_custom())
}
Self::InvalidInnerEnvelopeError => ProtocolError::InvalidInnerEnvelopeError,
Self::ServerError => ProtocolError::ServerError,
Self::ServerInvalidEnvelopeCredentialsFormatError => {
ProtocolError::ServerInvalidEnvelopeCredentialsFormatError
}
Self::ClientError => ProtocolError::ClientError,
Self::InvalidLoginError => ProtocolError::InvalidLoginError,
Self::SerializationError => ProtocolError::SerializationError,
Self::ReflectedValueError => ProtocolError::ReflectedValueError,
Self::IdentityGroupElementError => ProtocolError::IdentityGroupElementError,
}
}
}
@@ -303,9 +178,9 @@ pub(crate) mod utils {
slice: &'a [u8],
expected_len: usize,
arg_name: &'static str,
) -> Result<&'a [u8], InternalPakeError<T>> {
) -> Result<&'a [u8], InternalError<T>> {
if slice.len() != expected_len {
return Err(InternalPakeError::SizeError {
return Err(InternalError::SizeError {
name: arg_name,
len: expected_len,
actual_len: slice.len(),
@@ -318,9 +193,9 @@ pub(crate) mod utils {
slice: &'a [u8],
expected_len: usize,
arg_name: &'static str,
) -> Result<&'a [u8], InternalPakeError> {
) -> Result<&'a [u8], InternalError> {
if slice.len() < expected_len {
return Err(InternalPakeError::SizeError {
return Err(InternalError::SizeError {
name: arg_name,
len: expected_len,
actual_len: slice.len(),
+4 -4
View File
@@ -3,7 +3,7 @@
// This source code is licensed under the MIT license found in the
// 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::serialization::i2osp;
use alloc::vec::Vec;
@@ -16,9 +16,9 @@ fn div_ceil(x: usize, y: usize) -> usize {
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() {
return Err(InternalPakeError::HashToCurveError);
return Err(InternalError::HashToCurveError);
}
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);
if ell > 255 {
return Err(InternalPakeError::HashToCurveError.into());
return Err(InternalError::HashToCurveError.into());
}
let dst_prime = [dst, &i2osp(dst.len(), 1)?].concat();
let z_pad = i2osp(0, r_in_bytes)?;
+3 -3
View File
@@ -12,7 +12,7 @@ pub(crate) mod p256;
mod ristretto;
mod x25519;
use crate::errors::{InternalPakeError, ProtocolError};
use crate::errors::{InternalError, ProtocolError};
use crate::hash::Hash;
use core::ops::Mul;
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
fn from_scalar_slice(
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
) -> Result<Self::Scalar, InternalPakeError>;
) -> Result<Self::Scalar, InternalError>;
/// picks a scalar at random
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar;
/// 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
fn from_element_slice(
element_bits: &GenericArray<u8, Self::ElemLen>,
) -> Result<Self, InternalPakeError>;
) -> Result<Self, InternalError>;
/// Serializes the `self` group element
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen>;
+6 -6
View File
@@ -9,7 +9,7 @@
)]
use super::Group;
use crate::errors::{InternalPakeError, ProtocolError};
use crate::errors::{InternalError, ProtocolError};
use crate::hash::Hash;
use core::ops::{Add, Div, Mul, Neg, Sub};
use core::str::FromStr;
@@ -71,12 +71,12 @@ impl Group for ProjectivePoint {
let p0 = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates(
&q0x, &q0y, false,
))
.ok_or(InternalPakeError::PointError)?
.ok_or(InternalError::PointError)?
.to_curve();
let p1 = AffinePoint::from_encoded_point(&EncodedPoint::from_affine_coordinates(
&q1x, &q1y, false,
))
.ok_or(InternalPakeError::PointError)?;
.ok_or(InternalError::PointError)?;
Ok(p0 + p1)
}
@@ -113,7 +113,7 @@ impl Group for ProjectivePoint {
fn from_scalar_slice(
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
) -> Result<Self::Scalar, InternalPakeError> {
) -> Result<Self::Scalar, InternalError> {
Ok(Self::Scalar::from_bytes_reduced(scalar_bits))
}
@@ -131,8 +131,8 @@ impl Group for ProjectivePoint {
fn from_element_slice(
element_bits: &GenericArray<u8, Self::ElemLen>,
) -> Result<Self, InternalPakeError> {
Option::from(Self::from_bytes(element_bits)).ok_or(InternalPakeError::PointError)
) -> Result<Self, InternalError> {
Option::from(Self::from_bytes(element_bits)).ok_or(InternalError::PointError)
}
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
+6 -6
View File
@@ -4,7 +4,7 @@
// LICENSE file in the root directory of this source tree.
use super::Group;
use crate::errors::{InternalPakeError, ProtocolError};
use crate::errors::{InternalError, ProtocolError};
use crate::hash::Hash;
use core::convert::TryInto;
use curve25519_dalek::{
@@ -30,7 +30,7 @@ impl Group for RistrettoPoint {
uniform_bytes
.as_slice()
.try_into()
.map_err(|_| InternalPakeError::HashToCurveError)?,
.map_err(|_| InternalError::HashToCurveError)?,
))
}
@@ -43,7 +43,7 @@ impl Group for RistrettoPoint {
uniform_bytes
.as_slice()
.try_into()
.map_err(|_| InternalPakeError::HashToCurveError)?,
.map_err(|_| InternalError::HashToCurveError)?,
))
}
@@ -51,7 +51,7 @@ impl Group for RistrettoPoint {
type ScalarLen = U32;
fn from_scalar_slice(
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
) -> Result<Self::Scalar, InternalPakeError> {
) -> Result<Self::Scalar, InternalError> {
Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
}
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
@@ -89,10 +89,10 @@ impl Group for RistrettoPoint {
type ElemLen = U32;
fn from_element_slice(
element_bits: &GenericArray<u8, Self::ElemLen>,
) -> Result<Self, InternalPakeError> {
) -> Result<Self, InternalError> {
CompressedRistretto::from_slice(element_bits)
.decompress()
.ok_or(InternalPakeError::PointError)
.ok_or(InternalError::PointError)
}
// serialization of a group element
fn to_arr(&self) -> GenericArray<u8, Self::ElemLen> {
+6 -8
View File
@@ -4,7 +4,7 @@
// LICENSE file in the root directory of this source tree.
use super::Group;
use crate::errors::{InternalPakeError, ProtocolError};
use crate::errors::{InternalError, ProtocolError};
use crate::hash::Hash;
use curve25519_dalek::{constants::X25519_BASEPOINT, montgomery::MontgomeryPoint, scalar::Scalar};
use generic_array::{typenum::U32, GenericArray};
@@ -26,7 +26,7 @@ impl Group for MontgomeryPoint {
type ScalarLen = U32;
fn from_scalar_slice(
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
) -> Result<Self::Scalar, InternalPakeError> {
) -> Result<Self::Scalar, InternalError> {
Ok(Scalar::from_bytes_mod_order(*scalar_bits.as_ref()))
}
fn random_nonzero_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Self::Scalar {
@@ -64,7 +64,7 @@ impl Group for MontgomeryPoint {
type ElemLen = U32;
fn from_element_slice(
element_bits: &GenericArray<u8, Self::ElemLen>,
) -> Result<Self, InternalPakeError> {
) -> Result<Self, InternalError> {
Ok(Self(*element_bits.as_ref()))
}
// serialization of a group element
@@ -93,8 +93,8 @@ impl Group for MontgomeryPoint {
#[test]
fn test() -> Result<(), ProtocolError> {
use crate::{
errors::PakeError, key_exchange::tripledh::TripleDH, slow_hash::NoOpHash, CipherSuite,
ClientLogin, ClientLoginFinishParameters, ClientLoginFinishResult, ClientLoginStartResult,
key_exchange::tripledh::TripleDH, slow_hash::NoOpHash, CipherSuite, ClientLogin,
ClientLoginFinishParameters, ClientLoginFinishResult, ClientLoginStartResult,
ClientRegistration, ClientRegistrationFinishParameters, ClientRegistrationFinishResult,
ClientRegistrationStartResult, ServerLogin, ServerLoginStartParameters,
ServerLoginStartResult, ServerRegistration, ServerSetup,
@@ -173,9 +173,7 @@ fn test() -> Result<(), ProtocolError> {
assert!(matches!(
client.finish(message, ClientLoginFinishParameters::Default),
Err(ProtocolError::VerificationError(
PakeError::InvalidLoginError
))
Err(ProtocolError::InvalidLoginError)
));
Ok(())
+2 -2
View File
@@ -5,7 +5,7 @@
use crate::{
ciphersuite::CipherSuite,
errors::{PakeError, ProtocolError},
errors::ProtocolError,
group::Group,
hash::Hash,
keypair::{PrivateKey, PublicKey, SecretKey},
@@ -83,7 +83,7 @@ pub trait KeyExchange<D: Hash, G: Group> {
}
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 {
+18 -22
View File
@@ -8,7 +8,7 @@ use crate::{
ciphersuite::CipherSuite,
errors::{
utils::{check_slice_size, check_slice_size_atleast},
InternalPakeError, PakeError, ProtocolError,
InternalError, ProtocolError,
},
group::Group,
hash::Hash,
@@ -88,7 +88,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
let mut transcript_hasher = D::new()
.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(&serialized_credential_request[..])
.chain(&id_s)
@@ -109,7 +109,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
)?;
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());
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 =
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());
if server_mac.verify(&ke2_message.mac).is_err() {
return Err(ProtocolError::VerificationError(
PakeError::KeyExchangeMacValidationError,
));
return Err(ProtocolError::InvalidLoginError);
}
transcript_hasher.update(ke2_message.mac.to_vec());
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());
Ok((
@@ -200,13 +198,11 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
ke2_state: &Self::KE2State,
) -> Result<Vec<u8>, ProtocolError> {
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);
if client_mac.verify(&ke3_message.mac).is_err() {
return Err(ProtocolError::VerificationError(
PakeError::KeyExchangeMacValidationError,
));
return Err(ProtocolError::InvalidLoginError);
}
Ok(ke2_state.session_key.to_vec())
@@ -256,7 +252,7 @@ pub struct Ke1Message<G: Group> {
}
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 nonce_len = NonceLen::USIZE;
@@ -293,7 +289,7 @@ impl<G: Group> ToBytes 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 checked_nonce = check_slice_size(
ke1_message_bytes,
@@ -363,7 +359,7 @@ pub struct Ke2Message<G: Group, HashLen: ArrayLength<u8>> {
}
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 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> {
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 nonce_len = NonceLen::USIZE;
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> {
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")?;
Ok(Self {
@@ -481,11 +477,11 @@ fn derive_3dh_keys<D: Hash, G: Group, S: SecretKey<G>>(
let ikm: Vec<u8> = [
&dh.sk1
.diffie_hellman(dh.pk1)
.map_err(InternalPakeError::into_custom)?[..],
.map_err(InternalError::into_custom)?[..],
&dh.sk2.diffie_hellman(dh.pk2)?[..],
&dh.sk3
.diffie_hellman(dh.pk3)
.map_err(InternalPakeError::into_custom)?[..],
.map_err(InternalError::into_custom)?[..],
]
.concat();
@@ -533,7 +529,7 @@ fn hkdf_expand_label<D: Hash>(
context: &[u8],
length: usize,
) -> 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)
}
@@ -547,7 +543,7 @@ fn hkdf_expand_label_extracted<D: Hash>(
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());
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.expand(&hkdf_label, &mut okm)
.map_err(|_| InternalPakeError::HkdfError)?;
.map_err(|_| InternalError::HkdfError)?;
Ok(okm)
}
+17 -19
View File
@@ -7,7 +7,7 @@
#![allow(unsafe_code)]
use crate::errors::{InternalPakeError, ProtocolError};
use crate::errors::{InternalError, ProtocolError};
use crate::group::Group;
use alloc::vec::Vec;
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
/// representation (i.e. can be mapped to a curve point), but presents
/// 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)
}
@@ -256,44 +256,44 @@ impl<G: Group> PrivateKey<G> {
}
/// 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 {
Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
} else {
Err(InternalPakeError::InvalidByteSequence)
Err(InternalError::InvalidByteSequence)
}
}
}
/// A trait specifying the requirements for a private key container
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;
/// 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
fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError<Self::Error>>;
fn public_key(&self) -> Result<PublicKey<G>, InternalError<Self::Error>>;
/// Serialization into bytes
fn serialize(&self) -> Vec<u8>;
/// 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> {
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 point = G::from_element_slice(pk_data)?;
let secret_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
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[..]);
Ok(PublicKey(Key(G::base_point()
.mult_by_slice(bytes_data)
@@ -304,8 +304,8 @@ impl<G: Group> SecretKey<G> for PrivateKey<G> {
self.to_vec()
}
fn deserialize(input: &[u8]) -> Result<Self, InternalPakeError> {
PrivateKey::from_bytes(input).map_err(InternalPakeError::from)
fn deserialize(input: &[u8]) -> Result<Self, InternalError> {
PrivateKey::from_bytes(input).map_err(InternalError::from)
}
}
@@ -351,11 +351,11 @@ impl<G: Group> PublicKey<G> {
}
/// 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 {
Ok(Self::from_arr(GenericArray::from_slice(key_bytes).clone()))
} else {
Err(InternalPakeError::InvalidByteSequence)
Err(InternalError::InvalidByteSequence)
}
}
}
@@ -471,13 +471,11 @@ mod tests {
fn diffie_hellman(
&self,
pk: PublicKey<RistrettoPoint>,
) -> Result<Vec<u8>, InternalPakeError<Self::Error>> {
) -> Result<Vec<u8>, InternalError<Self::Error>> {
self.0.diffie_hellman(pk)
}
fn public_key(
&self,
) -> Result<PublicKey<RistrettoPoint>, InternalPakeError<Self::Error>> {
fn public_key(&self) -> Result<PublicKey<RistrettoPoint>, InternalError<Self::Error>> {
self.0.public_key()
}
@@ -485,7 +483,7 @@ mod tests {
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)
}
}
+6 -6
View File
@@ -748,7 +748,7 @@
//! ```
//! # use curve25519_dalek::ristretto::RistrettoPoint;
//! # 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 zeroize::Zeroize;
//! # struct Default;
@@ -773,14 +773,14 @@
//! fn diffie_hellman(
//! &self,
//! pk: PublicKey<RistrettoPoint>,
//! ) -> Result<Vec<u8>, InternalPakeError<Self::Error>> {
//! YourRemoteKey::diffie_hellman(self, &pk.to_arr()).map_err(InternalPakeError::Custom)
//! ) -> Result<Vec<u8>, InternalError<Self::Error>> {
//! YourRemoteKey::diffie_hellman(self, &pk.to_arr()).map_err(InternalError::Custom)
//! }
//!
//! fn public_key(
//! &self
//! ) -> Result<PublicKey<RistrettoPoint>, InternalPakeError<Self::Error>> {
//! YourRemoteKey::public_key(self).map(PublicKey::from_arr).map_err(InternalPakeError::Custom)
//! ) -> Result<PublicKey<RistrettoPoint>, InternalError<Self::Error>> {
//! YourRemoteKey::public_key(self).map(PublicKey::from_arr).map_err(InternalError::Custom)
//! }
//!
//! fn serialize(&self) -> Vec<u8> {
@@ -788,7 +788,7 @@
//! 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
//! todo!()
//! }
+5 -5
View File
@@ -10,7 +10,7 @@ use crate::{
envelope::Envelope,
errors::{
utils::{check_slice_size, check_slice_size_atleast},
PakeError, ProtocolError,
ProtocolError,
},
group::Group,
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
if alpha.is_identity() {
return Err(PakeError::IdentityGroupElementError.into());
return Err(ProtocolError::IdentityGroupElementError);
}
Ok(Self { alpha })
}
@@ -118,7 +118,7 @@ impl<CS: CipherSuite> RegistrationResponse<CS> {
// Throw an error if the identity group element is encountered
if beta.is_identity() {
return Err(PakeError::IdentityGroupElementError.into());
return Err(ProtocolError::IdentityGroupElementError);
}
// 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
if alpha.is_identity() {
return Err(PakeError::IdentityGroupElementError.into());
return Err(ProtocolError::IdentityGroupElementError);
}
let ke1_message =
@@ -347,7 +347,7 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
// Throw an error if the identity group element is encountered
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();
+17 -26
View File
@@ -8,7 +8,7 @@
use crate::{
ciphersuite::CipherSuite,
envelope::Envelope,
errors::{utils::check_slice_size, InternalPakeError, PakeError, ProtocolError},
errors::{utils::check_slice_size, InternalError, ProtocolError},
group::Group,
hash::Hash,
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 min_expected_len = elem_len + scalar_len;
let checked_slice = (if input.len() <= min_expected_len {
Err(InternalPakeError::SizeError {
Err(InternalError::SizeError {
name: "client_registration_bytes",
len: min_expected_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 mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
h.expand(STR_MASKING_KEY, &mut masking_key)
.map_err(|_| InternalPakeError::HkdfError)?;
.map_err(|_| InternalError::HkdfError)?;
let result =
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> {
let scalar_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
let checked_slice = (if input.len() <= scalar_len {
Err(InternalPakeError::SizeError {
Err(InternalError::SizeError {
name: "client_login_bytes",
len: scalar_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 mut masking_key = vec![0u8; <CS::Hash as Digest>::OutputSize::USIZE];
h.expand(STR_MASKING_KEY, &mut masking_key)
.map_err(|_| InternalPakeError::HkdfError)?;
.map_err(|_| InternalError::HkdfError)?;
let (server_s_pk, envelope) = unmask_response::<CS>(
&masking_key,
@@ -673,10 +673,7 @@ impl<CS: CipherSuite> ClientLogin<CS> {
&credential_response.masked_response,
)
.map_err(|e| match e {
ProtocolError::InvalidInnerEnvelopeError => PakeError::InvalidLoginError.into(),
ProtocolError::VerificationError(PakeError::SerializationError) => {
PakeError::InvalidLoginError.into()
}
ProtocolError::SerializationError => ProtocolError::InvalidLoginError,
err => err,
})?;
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
.open(&password_derived_key, &server_s_pk_bytes, &optional_ids)
.map_err(|e| match e {
ProtocolError::VerificationError(PakeError::CryptoError(
InternalPakeError::SealOpenHmacError,
)) => ProtocolError::VerificationError(PakeError::InvalidLoginError),
ProtocolError::LibraryError(InternalError::SealOpenHmacError) => {
ProtocolError::InvalidLoginError
}
err => err,
})?;
@@ -930,13 +927,7 @@ impl<CS: CipherSuite> ServerLogin<CS> {
let session_key = <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::finish_ke(
message.ke3_message,
&self.ke2_state,
)
.map_err(|e| match e {
ProtocolError::VerificationError(PakeError::KeyExchangeMacValidationError) => {
ProtocolError::VerificationError(PakeError::InvalidLoginError)
}
err => err,
})?;
)?;
Ok(ServerLoginFinishResult {
session_key,
@@ -1030,9 +1021,9 @@ fn oprf_key_from_seed<G: Group, D: Hash>(
) -> Result<G::Scalar, ProtocolError> {
let mut ikm = vec![0u8; G::ScalarLen::USIZE];
Hkdf::<D>::from_prk(oprf_seed)
.map_err(|_| InternalPakeError::HkdfError)?
.map_err(|_| InternalError::HkdfError)?
.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)
}
@@ -1044,12 +1035,12 @@ fn mask_response<CS: CipherSuite>(
) -> Result<Vec<u8>, ProtocolError> {
let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
Hkdf::<CS::Hash>::from_prk(masking_key)
.map_err(|_| InternalPakeError::HkdfError)?
.map_err(|_| InternalError::HkdfError)?
.expand(
&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD].concat(),
&mut xor_pad,
)
.map_err(|_| InternalPakeError::HkdfError)?;
.map_err(|_| InternalError::HkdfError)?;
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> {
let mut xor_pad = vec![0u8; <CS::KeGroup as Group>::ElemLen::USIZE + Envelope::<CS>::len()];
Hkdf::<CS::Hash>::from_prk(masking_key)
.map_err(|_| InternalPakeError::HkdfError)?
.map_err(|_| InternalError::HkdfError)?
.expand(
&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD].concat(),
&mut xor_pad,
)
.map_err(|_| InternalPakeError::HkdfError)?;
.map_err(|_| InternalError::HkdfError)?;
let plaintext: Vec<u8> = xor_pad
.iter()
.zip(masked_response.iter())
@@ -1084,7 +1075,7 @@ fn unmask_response<CS: CipherSuite>(
// Ensure that public key is valid
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))
}
+12 -9
View File
@@ -3,16 +3,16 @@
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
use crate::errors::PakeError;
use crate::errors::ProtocolError;
use alloc::vec::Vec;
// 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>();
// Check if input >= 256^length
if (sizeof_usize as u32 - input.leading_zeros() / 8) > length as u32 {
return Err(PakeError::SerializationError);
return Err(ProtocolError::SerializationError);
}
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
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>() {
return Err(PakeError::SerializationError);
return Err(ProtocolError::SerializationError);
}
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
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())
}
// Tokenizes an input of the format I2OSP(len(input), max_bytes) || input, outputting
// (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 {
return Err(PakeError::SerializationError);
return Err(ProtocolError::SerializationError);
}
let size = os2ip(&input[..size_bytes])?;
if size_bytes + size > input.len() {
return Err(PakeError::SerializationError);
return Err(ProtocolError::SerializationError);
}
Ok((
+4 -4
View File
@@ -111,7 +111,7 @@ fn registration_request_roundtrip() {
assert!(
match RegistrationRequest::<Default>::deserialize(identity_bytes.as_slice()) {
Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
Err(ProtocolError::IdentityGroupElementError) => true,
_ => false,
}
);
@@ -140,7 +140,7 @@ fn registration_response_roundtrip() {
assert!(match RegistrationResponse::<Default>::deserialize(
&[identity_bytes, pubkey_bytes.to_vec()].concat()
) {
Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
Err(ProtocolError::IdentityGroupElementError) => true,
_ => false,
});
}
@@ -201,7 +201,7 @@ fn credential_request_roundtrip() {
assert!(match CredentialRequest::<Default>::deserialize(
&[identity_bytes, ke1m.to_vec()].concat()
) {
Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
Err(ProtocolError::IdentityGroupElementError) => true,
_ => false,
});
}
@@ -251,7 +251,7 @@ fn credential_response_roundtrip() {
]
.concat()
) {
Err(ProtocolError::VerificationError(PakeError::IdentityGroupElementError)) => true,
Err(ProtocolError::IdentityGroupElementError) => true,
_ => false,
});
}
+5 -11
View File
@@ -5,7 +5,7 @@
//! Trait specifying a slow hashing function
use crate::{errors::InternalPakeError, hash::Hash};
use crate::{errors::InternalError, hash::Hash};
use alloc::vec::Vec;
use digest::Digest;
#[cfg(feature = "slow-hash")]
@@ -15,27 +15,21 @@ use generic_array::GenericArray;
/// Used for the slow hashing function in OPAQUE
pub trait SlowHash<D: Hash> {
/// Computes the slow hashing function
fn hash(
input: GenericArray<u8, <D as Digest>::OutputSize>,
) -> Result<Vec<u8>, InternalPakeError>;
fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError>;
}
/// A no-op hash which simply returns its input
pub struct NoOpHash;
impl<D: Hash> SlowHash<D> for NoOpHash {
fn hash(
input: GenericArray<u8, <D as Digest>::OutputSize>,
) -> Result<Vec<u8>, InternalPakeError> {
fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError> {
Ok(input.to_vec())
}
}
#[cfg(feature = "slow-hash")]
impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
fn hash(
input: GenericArray<u8, <D as Digest>::OutputSize>,
) -> Result<Vec<u8>, InternalPakeError> {
fn hash(input: GenericArray<u8, <D as Digest>::OutputSize>) -> Result<Vec<u8>, InternalError> {
let params = argon2::Argon2::default();
let mut output = alloc::vec![0u8; <D as Digest>::OutputSize::USIZE];
params
@@ -46,7 +40,7 @@ impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
&[],
&mut output,
)
.map_err(|_| InternalPakeError::SlowHashError)?;
.map_err(|_| InternalError::SlowHashError)?;
Ok(output)
}
}
+1 -1
View File
@@ -763,7 +763,7 @@ fn test_complete_flow(
);
} else {
assert!(match client_login_result {
Err(ProtocolError::VerificationError(PakeError::InvalidLoginError)) => true,
Err(ProtocolError::InvalidLoginError) => true,
_ => false,
});
}
+1 -1
View File
@@ -125,7 +125,7 @@ fn test_blind<G: Group, H: Hash>(tvs: &[&str]) -> Result<(), ProtocolError> {
}
// 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 {
let parameters = populate_test_vectors(&serde_json::from_str(tv).unwrap());
let evaluation_element = oprf::evaluate::<G>(