#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use crate::error::HpkeError;
use crate::security::CryptoRng;
use crate::types::{
HpkeAead,
HpkeCipherSuite,
HpkeKdf,
HpkeKem,
SecretBytes,
};
pub type KemPublicAndSecretBytes = (Vec<u8>, SecretBytes);
pub trait KemProvider {
fn generate_keypair(
&self,
kem: HpkeKem,
rng: &mut dyn CryptoRng,
) -> Result<KemPublicAndSecretBytes, HpkeError>;
fn encapsulate(
&self,
kem: HpkeKem,
public_key: &[u8],
rng: &mut dyn CryptoRng,
) -> Result<KemPublicAndSecretBytes, HpkeError>;
fn decapsulate(
&self,
kem: HpkeKem,
secret_key: &[u8],
ciphertext: &[u8],
) -> Result<SecretBytes, HpkeError>;
fn validate_key(&self, kem: HpkeKem, key: &[u8], is_secret: bool) -> Result<(), HpkeError>;
fn derive_public_key(&self, kem: HpkeKem, secret_key: &[u8]) -> Result<Vec<u8>, HpkeError>;
fn supports_kem(&self, kem: HpkeKem) -> bool;
fn auth_encapsulate(
&self,
kem: HpkeKem,
sender_sk: &[u8],
recipient_pk: &[u8],
rng: &mut dyn CryptoRng,
) -> Result<KemPublicAndSecretBytes, HpkeError>;
fn auth_decapsulate(
&self,
kem: HpkeKem,
encapsulated_key: &[u8],
recipient_sk: &[u8],
sender_pk: &[u8],
) -> Result<SecretBytes, HpkeError>;
}
pub trait KdfProvider {
fn extract(&self, kdf: HpkeKdf, salt: &[u8], ikm: &[u8]) -> Result<Vec<u8>, HpkeError>;
fn expand(
&self,
kdf: HpkeKdf,
prk: &[u8],
info: &[u8],
output_len: usize,
) -> Result<Vec<u8>, HpkeError>;
fn supports_kdf(&self, kdf: HpkeKdf) -> bool;
}
pub trait AeadProvider {
fn seal(
&self,
aead: HpkeAead,
key: &[u8],
nonce: &[u8],
aad: &[u8],
plaintext: &[u8],
) -> Result<Vec<u8>, HpkeError>;
fn open(
&self,
aead: HpkeAead,
key: &[u8],
nonce: &[u8],
aad: &[u8],
ciphertext: &[u8],
) -> Result<Vec<u8>, HpkeError>;
fn validate_key(&self, aead: HpkeAead, key: &[u8]) -> Result<(), HpkeError>;
fn validate_nonce(&self, aead: HpkeAead, nonce: &[u8]) -> Result<(), HpkeError>;
fn supports_aead(&self, aead: HpkeAead) -> bool;
}
pub trait HpkeCryptoProvider: KemProvider + KdfProvider + AeadProvider {
fn name(&self) -> &'static str;
fn supported_algorithms(&self) -> SupportedAlgorithms;
}
#[derive(Debug, Clone, PartialEq)]
pub struct SupportedAlgorithms {
pub kems: Vec<HpkeKem>,
pub kdfs: Vec<HpkeKdf>,
pub aeads: Vec<HpkeAead>,
}
impl SupportedAlgorithms {
pub fn new(kems: Vec<HpkeKem>, kdfs: Vec<HpkeKdf>, aeads: Vec<HpkeAead>) -> Self {
Self { kems, kdfs, aeads }
}
pub fn supports_kem(&self, kem: HpkeKem) -> bool {
self.kems.contains(&kem)
}
pub fn supports_kdf(&self, kdf: HpkeKdf) -> bool {
self.kdfs.contains(&kdf)
}
pub fn supports_aead(&self, aead: HpkeAead) -> bool {
self.aeads.contains(&aead)
}
pub fn supports_cipher_suite(&self, suite: &HpkeCipherSuite) -> bool {
self.supports_kem(suite.kem) &&
self.supports_kdf(suite.kdf) &&
self.supports_aead(suite.aead)
}
}