use crypto_core::{
AeadAlgorithm, CryptoError, HashAlgorithm, MacAlgorithm, MacFailureKind, MacHash,
};
use zeroize::Zeroizing;
pub use crypto_dispatch::{
derive_keypair, derive_shared_secret, generate_keypair, generate_multikey_keypair,
kem_decapsulate, kem_encapsulate, provider_decision, public_key_to_multikey, sign,
validate_verification_method_multikey, verify, AlgorithmError, FallbackPolicy,
GeneratedKeypair, KeyCopyBoundary, KeyResidency, ProviderDecision, ProviderDisposition,
ProviderKind, ProviderLane, ProviderOperation, ProviderOutputPolicy, ProviderPolicyReason,
};
pub struct AeadParams<'a> {
pub key: &'a [u8],
pub nonce: &'a [u8],
pub aad: &'a [u8],
}
pub struct MacParams<'a> {
pub key: &'a [u8],
}
pub fn hash_digest(algorithm: HashAlgorithm, message: &[u8]) -> Result<Vec<u8>, AlgorithmError> {
crate::operations::hash::digest(algorithm, message).map_err(|error| match error {
crate::operations::OperationError::Provider {
reason: crate::operations::ProviderErrorReason::UnsupportedAlgorithm,
} => AlgorithmError::UnsupportedHashAlgorithm(algorithm),
_ => AlgorithmError::Crypto(CryptoError::Unsupported),
})
}
pub fn aead_encrypt(
algorithm: AeadAlgorithm,
params: &AeadParams<'_>,
plaintext: &[u8],
) -> Result<Vec<u8>, AlgorithmError> {
crate::operations::aead::seal(algorithm, params.key, params.nonce, params.aad, plaintext)
.map_err(|error| {
aead_algorithm_error_from_operation_error(
algorithm,
crate::aead_error::AeadOperation::Seal,
error,
params.key.len(),
params.nonce.len(),
plaintext.len(),
)
})
}
pub fn aead_decrypt(
algorithm: AeadAlgorithm,
params: &AeadParams<'_>,
ciphertext_with_tag: &[u8],
) -> Result<Zeroizing<Vec<u8>>, AlgorithmError> {
crate::operations::aead::open(
algorithm,
params.key,
params.nonce,
params.aad,
ciphertext_with_tag,
)
.map_err(|error| {
aead_algorithm_error_from_operation_error(
algorithm,
crate::aead_error::AeadOperation::Open,
error,
params.key.len(),
params.nonce.len(),
ciphertext_with_tag.len(),
)
})
}
fn aead_algorithm_error_from_operation_error(
algorithm: AeadAlgorithm,
operation: crate::aead_error::AeadOperation,
error: crate::operations::OperationError,
key_len: usize,
nonce_len: usize,
input_len: usize,
) -> AlgorithmError {
match error {
crate::operations::OperationError::Provider {
reason: crate::operations::ProviderErrorReason::UnsupportedAlgorithm,
} => AlgorithmError::UnsupportedAeadAlgorithm(algorithm),
_ => AlgorithmError::Crypto(crate::aead_error::crypto_error_from_operation_error(
algorithm, operation, error, key_len, nonce_len, input_len,
)),
}
}
pub fn mac_authenticate(
algorithm: MacAlgorithm,
params: &MacParams<'_>,
message: &[u8],
) -> Result<Vec<u8>, AlgorithmError> {
crate::operations::mac::authenticate(algorithm, params.key, message)
.map_err(|error| mac_algorithm_error_from_operation_error(algorithm, error))
}
pub fn mac_verify(
algorithm: MacAlgorithm,
params: &MacParams<'_>,
message: &[u8],
tag: &[u8],
) -> Result<(), AlgorithmError> {
crate::operations::mac::verify(algorithm, params.key, message, tag)
.map_err(|error| mac_algorithm_error_from_operation_error(algorithm, error))
}
fn mac_algorithm_error_from_operation_error(
algorithm: MacAlgorithm,
error: crate::operations::OperationError,
) -> AlgorithmError {
let kind = match error {
crate::operations::OperationError::Primitive {
reason: crate::operations::PrimitiveErrorReason::InvalidKey,
} => MacFailureKind::InvalidKeyLength,
crate::operations::OperationError::Primitive {
reason: crate::operations::PrimitiveErrorReason::InvalidLength,
} => MacFailureKind::InvalidTagLength,
crate::operations::OperationError::Primitive {
reason: crate::operations::PrimitiveErrorReason::VerificationFailed,
} => MacFailureKind::VerificationFailed,
crate::operations::OperationError::Provider {
reason: crate::operations::ProviderErrorReason::UnsupportedAlgorithm,
} => return AlgorithmError::UnsupportedMacAlgorithm(algorithm),
_ => MacFailureKind::BackendFailure,
};
AlgorithmError::Crypto(CryptoError::Mac {
hash: mac_hash(algorithm),
kind,
})
}
fn mac_hash(algorithm: MacAlgorithm) -> MacHash {
match algorithm {
MacAlgorithm::HmacSha256 => MacHash::Sha2_256,
MacAlgorithm::HmacSha384 => MacHash::Sha2_384,
MacAlgorithm::HmacSha512 => MacHash::Sha2_512,
}
}