use crate::error::IntoAnyError;
use alloc::vec;
use alloc::vec::Vec;
use core::{
fmt::{self, Debug},
ops::Deref,
};
use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
use zeroize::{ZeroizeOnDrop, Zeroizing};
mod cipher_suite;
pub use self::cipher_suite::*;
#[cfg(feature = "test_suite")]
pub mod test_suite;
#[derive(Clone, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct HpkeCiphertext {
#[mls_codec(with = "mls_rs_codec::byte_vec")]
#[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
pub kem_output: Vec<u8>,
#[mls_codec(with = "mls_rs_codec::byte_vec")]
#[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
pub ciphertext: Vec<u8>,
}
impl Debug for HpkeCiphertext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("HpkeCiphertext").finish()
}
}
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord, MlsSize, MlsDecode, MlsEncode)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct HpkePublicKey(
#[mls_codec(with = "mls_rs_codec::byte_vec")]
#[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
Vec<u8>,
);
impl Debug for HpkePublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
crate::debug::pretty_bytes(&self.0)
.named("HpkePublicKey")
.fmt(f)
}
}
impl From<Vec<u8>> for HpkePublicKey {
fn from(data: Vec<u8>) -> Self {
Self(data)
}
}
impl From<HpkePublicKey> for Vec<u8> {
fn from(data: HpkePublicKey) -> Self {
data.0
}
}
impl Deref for HpkePublicKey {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl AsRef<[u8]> for HpkePublicKey {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
#[derive(Clone, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode, ZeroizeOnDrop)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct HpkeSecretKey(
#[mls_codec(with = "mls_rs_codec::byte_vec")]
#[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
Vec<u8>,
);
impl Debug for HpkeSecretKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("HpkeSecretKey").finish()
}
}
impl From<Vec<u8>> for HpkeSecretKey {
fn from(data: Vec<u8>) -> Self {
Self(data)
}
}
impl Deref for HpkeSecretKey {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl AsRef<[u8]> for HpkeSecretKey {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
#[derive(Clone, Debug, PartialEq, Eq, Default)]
pub struct HpkePsk<'a> {
pub id: &'a [u8],
pub value: &'a [u8],
}
impl<'a> HpkePsk<'a> {
pub fn new(id: &'a [u8], value: &'a [u8]) -> Self {
Self { id, value }
}
}
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
#[cfg_attr(
all(not(target_arch = "wasm32"), mls_build_async),
maybe_async::must_be_async
)]
pub trait HpkeContextS {
type Error: IntoAnyError;
async fn seal(&mut self, aad: Option<&[u8]>, data: &[u8]) -> Result<Vec<u8>, Self::Error>;
async fn export(
&self,
exporter_context: &[u8],
len: usize,
) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
}
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
#[cfg_attr(
all(not(target_arch = "wasm32"), mls_build_async),
maybe_async::must_be_async
)]
pub trait HpkeContextR {
type Error: IntoAnyError;
async fn open(
&mut self,
aad: Option<&[u8]>,
ciphertext: &[u8],
) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
async fn export(
&self,
exporter_context: &[u8],
len: usize,
) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
}
#[derive(Clone, PartialEq, Eq, Hash, Ord, PartialOrd, MlsSize, MlsEncode, MlsDecode)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SignaturePublicKey(
#[mls_codec(with = "mls_rs_codec::byte_vec")]
#[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
Vec<u8>,
);
impl Debug for SignaturePublicKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
crate::debug::pretty_bytes(&self.0)
.named("SignaturePublicKey")
.fmt(f)
}
}
impl SignaturePublicKey {
pub fn new(bytes: Vec<u8>) -> Self {
bytes.into()
}
pub fn new_slice(data: &[u8]) -> Self {
Self(data.to_vec())
}
pub fn as_bytes(&self) -> &[u8] {
&self.0
}
}
impl Deref for SignaturePublicKey {
type Target = [u8];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl AsRef<[u8]> for SignaturePublicKey {
fn as_ref(&self) -> &[u8] {
&self.0
}
}
impl From<Vec<u8>> for SignaturePublicKey {
fn from(data: Vec<u8>) -> Self {
SignaturePublicKey(data)
}
}
impl From<SignaturePublicKey> for Vec<u8> {
fn from(value: SignaturePublicKey) -> Self {
value.0
}
}
#[derive(Clone, PartialEq, Eq, ZeroizeOnDrop, MlsSize, MlsEncode, MlsDecode)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SignatureSecretKey {
#[mls_codec(with = "mls_rs_codec::byte_vec")]
#[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))]
bytes: Vec<u8>,
}
impl Debug for SignatureSecretKey {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SignatureSecretKey").finish()
}
}
impl SignatureSecretKey {
pub fn new(bytes: Vec<u8>) -> Self {
bytes.into()
}
pub fn new_slice(data: &[u8]) -> Self {
Self {
bytes: data.to_vec(),
}
}
pub fn as_bytes(&self) -> &[u8] {
&self.bytes
}
}
impl From<Vec<u8>> for SignatureSecretKey {
fn from(bytes: Vec<u8>) -> Self {
Self { bytes }
}
}
impl Deref for SignatureSecretKey {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.bytes
}
}
impl AsRef<[u8]> for SignatureSecretKey {
fn as_ref(&self) -> &[u8] {
&self.bytes
}
}
pub trait CryptoProvider: Send + Sync {
type CipherSuiteProvider: CipherSuiteProvider + Clone;
fn supported_cipher_suites(&self) -> Vec<CipherSuite>;
fn cipher_suite_provider(&self, cipher_suite: CipherSuite)
-> Option<Self::CipherSuiteProvider>;
}
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
#[cfg_attr(all(target_arch = "wasm32", mls_build_async), maybe_async::must_be_async(?Send))]
#[cfg_attr(
all(not(target_arch = "wasm32"), mls_build_async),
maybe_async::must_be_async
)]
pub trait CipherSuiteProvider: Send + Sync {
type Error: IntoAnyError;
type HpkeContextS: HpkeContextS + Send + Sync;
type HpkeContextR: HpkeContextR + Send + Sync;
fn cipher_suite(&self) -> CipherSuite;
async fn hash(&self, data: &[u8]) -> Result<Vec<u8>, Self::Error>;
async fn mac(&self, key: &[u8], data: &[u8]) -> Result<Vec<u8>, Self::Error>;
async fn aead_seal(
&self,
key: &[u8],
data: &[u8],
aad: Option<&[u8]>,
nonce: &[u8],
) -> Result<Vec<u8>, Self::Error>;
async fn aead_open(
&self,
key: &[u8],
ciphertext: &[u8],
aad: Option<&[u8]>,
nonce: &[u8],
) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
fn aead_key_size(&self) -> usize;
fn aead_nonce_size(&self) -> usize;
async fn kdf_extract(&self, salt: &[u8], ikm: &[u8])
-> Result<Zeroizing<Vec<u8>>, Self::Error>;
async fn kdf_expand(
&self,
prk: &[u8],
info: &[u8],
len: usize,
) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
fn kdf_extract_size(&self) -> usize;
async fn hpke_seal(
&self,
remote_key: &HpkePublicKey,
info: &[u8],
aad: Option<&[u8]>,
pt: &[u8],
) -> Result<HpkeCiphertext, Self::Error>;
async fn hpke_seal_psk(
&self,
remote_key: &HpkePublicKey,
info: &[u8],
aad: Option<&[u8]>,
pt: &[u8],
psk: HpkePsk<'_>,
) -> Result<HpkeCiphertext, Self::Error>;
async fn hpke_open(
&self,
ciphertext: &HpkeCiphertext,
local_secret: &HpkeSecretKey,
local_public: &HpkePublicKey,
info: &[u8],
aad: Option<&[u8]>,
) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
async fn hpke_open_psk(
&self,
ciphertext: &HpkeCiphertext,
local_secret: &HpkeSecretKey,
local_public: &HpkePublicKey,
info: &[u8],
aad: Option<&[u8]>,
psk: HpkePsk<'_>,
) -> Result<Zeroizing<Vec<u8>>, Self::Error>;
async fn hpke_setup_s(
&self,
remote_key: &HpkePublicKey,
info: &[u8],
) -> Result<(Vec<u8>, Self::HpkeContextS), Self::Error>;
async fn hpke_setup_r(
&self,
kem_output: &[u8],
local_secret: &HpkeSecretKey,
local_public: &HpkePublicKey,
info: &[u8],
) -> Result<Self::HpkeContextR, Self::Error>;
async fn kem_derive(&self, ikm: &[u8]) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>;
async fn kem_generate(&self) -> Result<(HpkeSecretKey, HpkePublicKey), Self::Error>;
fn kem_public_key_validate(&self, key: &HpkePublicKey) -> Result<(), Self::Error>;
fn random_bytes(&self, out: &mut [u8]) -> Result<(), Self::Error>;
fn random_bytes_vec(&self, count: usize) -> Result<Vec<u8>, Self::Error> {
let mut vec = vec![0u8; count];
self.random_bytes(&mut vec)?;
Ok(vec)
}
async fn signature_key_generate(
&self,
) -> Result<(SignatureSecretKey, SignaturePublicKey), Self::Error>;
async fn signature_key_derive_public(
&self,
secret_key: &SignatureSecretKey,
) -> Result<SignaturePublicKey, Self::Error>;
async fn sign(
&self,
secret_key: &SignatureSecretKey,
data: &[u8],
) -> Result<Vec<u8>, Self::Error>;
async fn verify(
&self,
public_key: &SignaturePublicKey,
signature: &[u8],
data: &[u8],
) -> Result<(), Self::Error>;
}