use std::ops::Range;
use super::*;
mod blake3digest512;
#[cfg(feature = "enable-crypto-none")]
pub(crate) mod none;
#[cfg(feature = "enable-crypto-vld0")]
pub(crate) mod vld0;
pub(crate) const VEILID_DOMAIN_API: &[u8] = b"VEILID_API";
#[cfg(feature = "enable-crypto-none")]
pub use none::sizes::*;
#[cfg(feature = "enable-crypto-none")]
pub use none::*;
#[cfg(feature = "enable-crypto-vld0")]
pub use vld0::sizes::*;
#[cfg(feature = "enable-crypto-vld0")]
pub use vld0::*;
pub use blake3digest512::*;
pub trait CryptoSystemBuffer: AsRef<[u8]> + AsMut<[u8]> {
fn len(&self) -> usize;
fn is_empty(&self) -> bool;
fn extend_from_slice(&mut self, other: &[u8]);
fn truncate(&mut self, len: usize);
}
impl CryptoSystemBuffer for Vec<u8> {
fn len(&self) -> usize {
Vec::<u8>::len(self)
}
fn is_empty(&self) -> bool {
Vec::<u8>::is_empty(self)
}
fn extend_from_slice(&mut self, other: &[u8]) {
Vec::<u8>::extend_from_slice(self, other);
}
fn truncate(&mut self, len: usize) {
Vec::<u8>::truncate(self, len);
}
}
impl CryptoSystemBuffer for BytesMut {
fn len(&self) -> usize {
BytesMut::len(self)
}
fn is_empty(&self) -> bool {
BytesMut::is_empty(self)
}
fn extend_from_slice(&mut self, other: &[u8]) {
BytesMut::extend_from_slice(self, other);
}
fn truncate(&mut self, len: usize) {
BytesMut::truncate(self, len);
}
}
pub trait CryptoSystem {
fn kind(&self) -> CryptoKind;
fn crypto(&self) -> VeilidComponentGuard<'_, Crypto>;
fn cached_dh(&self, key: &PublicKey, secret: &SecretKey) -> VeilidAPIResult<SharedSecret>;
fn random_bytes(&self, len: usize) -> Vec<u8>;
fn hash_password(&self, password: &[u8], salt: &[u8]) -> VeilidAPIResult<String>;
fn verify_password(&self, password: &[u8], password_hash: &str) -> VeilidAPIResult<bool>;
fn derive_shared_secret(&self, password: &[u8], salt: &[u8]) -> VeilidAPIResult<SharedSecret>;
fn random_nonce(&self) -> Nonce;
fn random_shared_secret(&self) -> SharedSecret;
fn compute_dh(&self, key: &PublicKey, secret: &SecretKey) -> VeilidAPIResult<SharedSecret>;
fn generate_shared_secret(
&self,
key: &PublicKey,
secret: &SecretKey,
domain: &[u8],
) -> VeilidAPIResult<SharedSecret> {
let dh = self.compute_dh(key, secret)?;
let hash = self.generate_hash(&[&dh.into_value(), domain, VEILID_DOMAIN_API].concat());
Ok(SharedSecret::new(
hash.kind(),
BareSharedSecret::new(&hash.into_value()),
))
}
fn generate_keypair(&self) -> KeyPair;
fn generate_hash(&self, data: &[u8]) -> HashDigest;
fn generate_hash_reader(&self, reader: &mut dyn std::io::Read) -> VeilidAPIResult<PublicKey>;
fn shared_secret_length(&self) -> usize;
fn nonce_length(&self) -> usize;
fn hash_digest_length(&self) -> usize;
fn public_key_length(&self) -> usize;
fn secret_key_length(&self) -> usize;
fn signature_length(&self) -> usize;
fn default_salt_length(&self) -> usize;
fn aead_overhead(&self) -> usize;
fn check_shared_secret(&self, secret: &SharedSecret) -> VeilidAPIResult<()> {
if secret.kind() != self.kind() {
apibail_generic!("incorrect shared secret kind");
}
if secret.value().len() != self.shared_secret_length() {
apibail_generic!(
"invalid shared secret length: {} != {}",
secret.value().len(),
self.shared_secret_length()
);
}
Ok(())
}
fn check_nonce(&self, nonce: &Nonce) -> VeilidAPIResult<()> {
if nonce.len() != self.nonce_length() {
apibail_generic!(
"invalid nonce length: {} != {}",
nonce.len(),
self.nonce_length()
);
}
Ok(())
}
fn check_hash_digest(&self, hash: &HashDigest) -> VeilidAPIResult<()> {
if hash.kind() != self.kind() {
apibail_generic!("incorrect hash digest kind");
}
if hash.value().len() != self.hash_digest_length() {
apibail_generic!(
"invalid hash digest length: {} != {}",
hash.value().len(),
self.hash_digest_length()
);
}
Ok(())
}
fn check_public_key(&self, key: &PublicKey) -> VeilidAPIResult<()> {
if key.kind() != self.kind() {
apibail_generic!("incorrect public key kind");
}
if key.value().len() != self.public_key_length() {
apibail_generic!(
"invalid public key length: {} != {}",
key.value().len(),
self.public_key_length()
);
}
Ok(())
}
fn check_secret_key(&self, key: &SecretKey) -> VeilidAPIResult<()> {
if key.kind() != self.kind() {
apibail_generic!("incorrect secret key kind");
}
if key.value().len() != self.secret_key_length() {
apibail_generic!(
"invalid secret key length: {} != {}",
key.value().len(),
self.secret_key_length()
);
}
Ok(())
}
fn check_signature(&self, signature: &Signature) -> VeilidAPIResult<()> {
if signature.kind() != self.kind() {
apibail_generic!("incorrect signature kind");
}
if signature.value().len() != self.signature_length() {
apibail_generic!(
"invalid signature length: {} != {}",
signature.value().len(),
self.signature_length()
);
}
Ok(())
}
fn check_keypair(&self, keypair: &KeyPair) -> VeilidAPIResult<()> {
if keypair.kind() != self.kind() {
apibail_generic!("incorrect keypair kind");
}
self.check_public_key(&keypair.key())?;
self.check_secret_key(&keypair.secret())?;
Ok(())
}
fn validate_keypair(&self, key: &PublicKey, secret: &SecretKey) -> VeilidAPIResult<bool>;
fn validate_hash(&self, data: &[u8], hash: &HashDigest) -> VeilidAPIResult<bool>;
fn validate_hash_reader(
&self,
reader: &mut dyn std::io::Read,
hash: &HashDigest,
) -> VeilidAPIResult<bool>;
fn sign(
&self,
public_key: &PublicKey,
secret: &SecretKey,
data: &[u8],
) -> VeilidAPIResult<Signature>;
fn sign_in_place(
&self,
public_key: &PublicKey,
secret: &SecretKey,
data: &mut [u8],
range: Range<usize>,
sig_idx: usize,
) -> VeilidAPIResult<()>;
fn verify(
&self,
public_key: &PublicKey,
data: &[u8],
signature: &Signature,
) -> VeilidAPIResult<bool>;
fn verify_in_place(
&self,
public_key: &PublicKey,
data: &[u8],
range: Range<usize>,
sig_idx: usize,
) -> VeilidAPIResult<bool>;
fn decrypt_in_place_aead(
&self,
body: &mut dyn CryptoSystemBuffer,
nonce: &Nonce,
shared_secret: &SharedSecret,
associated_data: Option<&[u8]>,
) -> VeilidAPIResult<()>;
fn decrypt_aead(
&self,
body: &[u8],
nonce: &Nonce,
shared_secret: &SharedSecret,
associated_data: Option<&[u8]>,
) -> VeilidAPIResult<Vec<u8>>;
fn encrypt_in_place_aead(
&self,
body: &mut dyn CryptoSystemBuffer,
nonce: &Nonce,
shared_secret: &SharedSecret,
associated_data: Option<&[u8]>,
) -> VeilidAPIResult<()>;
fn encrypt_aead(
&self,
body: &[u8],
nonce: &Nonce,
shared_secret: &SharedSecret,
associated_data: Option<&[u8]>,
) -> VeilidAPIResult<Vec<u8>>;
fn crypt_in_place_no_auth(
&self,
body: &mut [u8],
nonce: &Nonce,
shared_secret: &SharedSecret,
) -> VeilidAPIResult<()>;
fn crypt_b2b_no_auth(
&self,
in_buf: &[u8],
out_buf: &mut [u8],
nonce: &Nonce,
shared_secret: &SharedSecret,
) -> VeilidAPIResult<()>;
fn crypt_no_auth_aligned_8(
&self,
body: &[u8],
nonce: &Nonce,
shared_secret: &SharedSecret,
) -> VeilidAPIResult<Vec<u8>>;
fn crypt_no_auth_unaligned(
&self,
body: &[u8],
nonce: &Nonce,
shared_secret: &SharedSecret,
) -> VeilidAPIResult<Vec<u8>>;
}