use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AeadBackend {
Native,
Swift,
Wasm,
Kotlin,
}
impl core::fmt::Display for AeadBackend {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let name = match self {
AeadBackend::Native => "native",
AeadBackend::Swift => "swift",
AeadBackend::Wasm => "wasm",
AeadBackend::Kotlin => "kotlin",
};
write!(f, "{name}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum AeadFailureKind {
InvalidKeyMaterial,
LengthOverflow,
ShortCiphertext,
InvalidOutputLength,
AuthenticationFailed,
BackendFailure,
}
impl core::fmt::Display for AeadFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
AeadFailureKind::InvalidKeyMaterial => "invalid key material",
AeadFailureKind::LengthOverflow => "length overflow",
AeadFailureKind::ShortCiphertext => "ciphertext shorter than tag",
AeadFailureKind::InvalidOutputLength => "backend returned invalid output length",
AeadFailureKind::AuthenticationFailed => "authentication failed",
AeadFailureKind::BackendFailure => "backend failure",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SignatureBackend {
Native,
Swift,
Wasm,
Kotlin,
SecureEnclave,
}
impl core::fmt::Display for SignatureBackend {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let name = match self {
SignatureBackend::Native => "native",
SignatureBackend::Swift => "swift",
SignatureBackend::Wasm => "wasm",
SignatureBackend::Kotlin => "kotlin",
SignatureBackend::SecureEnclave => "secure_enclave",
};
write!(f, "{name}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SignatureOperation {
Sign,
Verify,
KeyManagement,
}
impl core::fmt::Display for SignatureOperation {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let op = match self {
SignatureOperation::Sign => "sign",
SignatureOperation::Verify => "verify",
SignatureOperation::KeyManagement => "key_management",
};
write!(f, "{op}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SignatureFailureKind {
BackendFailure,
InvalidPrivateKey,
InvalidPublicKey,
InvalidSignature,
InvalidMessage,
KeyGenerationFailed,
SecureEnclaveUnavailable,
SecureEnclaveRejectedKey,
}
impl core::fmt::Display for SignatureFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
SignatureFailureKind::BackendFailure => "backend failure",
SignatureFailureKind::InvalidPrivateKey => "invalid private key",
SignatureFailureKind::InvalidPublicKey => "invalid public key",
SignatureFailureKind::InvalidSignature => "invalid signature",
SignatureFailureKind::InvalidMessage => "invalid message",
SignatureFailureKind::KeyGenerationFailed => "key generation failed",
SignatureFailureKind::SecureEnclaveUnavailable => "secure enclave unavailable",
SignatureFailureKind::SecureEnclaveRejectedKey => "secure enclave rejected key",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyAgreementFailureKind {
DeriveSharedSecretFailed,
KeyGenerationFailed,
}
impl core::fmt::Display for KeyAgreementFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
KeyAgreementFailureKind::DeriveSharedSecretFailed => "derive shared secret failed",
KeyAgreementFailureKind::KeyGenerationFailed => "key generation failed",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KemFailureKind {
KeyGenerationFailed,
EncapsulateFailed,
DecapsulateFailed,
}
impl core::fmt::Display for KemFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
KemFailureKind::KeyGenerationFailed => "key generation failed",
KemFailureKind::EncapsulateFailed => "encapsulate failed",
KemFailureKind::DecapsulateFailed => "decapsulate failed",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyWrapAlgorithm {
Aes256Kw,
}
impl core::fmt::Display for KeyWrapAlgorithm {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
KeyWrapAlgorithm::Aes256Kw => "AES-256-KW",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyWrapOperation {
Wrap,
Unwrap,
}
impl core::fmt::Display for KeyWrapOperation {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let op = match self {
KeyWrapOperation::Wrap => "wrap",
KeyWrapOperation::Unwrap => "unwrap",
};
write!(f, "{op}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyWrapFailureKind {
InvalidKekLength,
InvalidPlaintextLength,
InvalidWrappedLength,
LengthOverflow,
IntegrityCheckFailed,
BackendFailure,
}
impl core::fmt::Display for KeyWrapFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
KeyWrapFailureKind::InvalidKekLength => "invalid key-encryption key length",
KeyWrapFailureKind::InvalidPlaintextLength => "invalid plaintext key length",
KeyWrapFailureKind::InvalidWrappedLength => "invalid wrapped key length",
KeyWrapFailureKind::LengthOverflow => "length overflow",
KeyWrapFailureKind::IntegrityCheckFailed => "integrity check failed",
KeyWrapFailureKind::BackendFailure => "backend failure",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KdfAlgorithm {
Argon2id,
Pbkdf2,
}
impl core::fmt::Display for KdfAlgorithm {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
KdfAlgorithm::Argon2id => "Argon2id",
KdfAlgorithm::Pbkdf2 => "PBKDF2",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KdfProfile {
Argon2idV1,
Argon2idV2,
Pbkdf2HmacSha256,
Pbkdf2HmacSha512,
}
impl core::fmt::Display for KdfProfile {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
KdfProfile::Argon2idV1 => "Argon2id v1",
KdfProfile::Argon2idV2 => "Argon2id v2",
KdfProfile::Pbkdf2HmacSha256 => "PBKDF2-HMAC-SHA-256",
KdfProfile::Pbkdf2HmacSha512 => "PBKDF2-HMAC-SHA-512",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KdfFailureKind {
InvalidSecretLength,
InvalidSaltLength,
InvalidOutputLength,
InvalidIterationCount,
InvalidParams,
DerivationFailed,
}
impl core::fmt::Display for KdfFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
KdfFailureKind::InvalidSecretLength => "invalid secret length",
KdfFailureKind::InvalidSaltLength => "invalid salt length",
KdfFailureKind::InvalidOutputLength => "invalid output length",
KdfFailureKind::InvalidIterationCount => "invalid iteration count",
KdfFailureKind::InvalidParams => "invalid parameters",
KdfFailureKind::DerivationFailed => "derivation failed",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HkdfHash {
Sha2_256,
Sha3_256,
}
impl core::fmt::Display for HkdfHash {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
HkdfHash::Sha2_256 => "SHA2-256",
HkdfHash::Sha3_256 => "SHA3-256",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum HkdfFailureKind {
InvalidIkmLength,
InvalidDomainTagLength,
InvalidDomainTagByte,
LengthOverflow,
InvalidOutputLength,
ExpandFailed,
}
impl core::fmt::Display for HkdfFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
HkdfFailureKind::InvalidIkmLength => "invalid input key material length",
HkdfFailureKind::InvalidDomainTagLength => "invalid domain tag length",
HkdfFailureKind::InvalidDomainTagByte => "invalid domain tag byte",
HkdfFailureKind::LengthOverflow => "length overflow",
HkdfFailureKind::InvalidOutputLength => "invalid output length",
HkdfFailureKind::ExpandFailed => "expand failed",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MacHash {
Sha2_256,
Sha2_512,
}
impl core::fmt::Display for MacHash {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
MacHash::Sha2_256 => "SHA-256",
MacHash::Sha2_512 => "SHA-512",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MacFailureKind {
InvalidKeyLength,
InvalidTagLength,
VerificationFailed,
BackendFailure,
}
impl core::fmt::Display for MacFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
MacFailureKind::InvalidKeyLength => "invalid key length",
MacFailureKind::InvalidTagLength => "invalid tag length",
MacFailureKind::VerificationFailed => "verification failed",
MacFailureKind::BackendFailure => "backend failure",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RngOutputKind {
Generic,
AeadNonce12,
Argon2Salt16,
Argon2Salt32,
}
impl core::fmt::Display for RngOutputKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
RngOutputKind::Generic => "random bytes",
RngOutputKind::AeadNonce12 => "AEAD nonce",
RngOutputKind::Argon2Salt16 => "Argon2 16-byte salt",
RngOutputKind::Argon2Salt32 => "Argon2 32-byte salt",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RngFailureKind {
EntropyUnavailable,
InvalidOutputLength,
}
impl core::fmt::Display for RngFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
RngFailureKind::EntropyUnavailable => "entropy unavailable",
RngFailureKind::InvalidOutputLength => "invalid output length",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConstantTimeFailureKind {
LengthMismatch,
NotEqual,
}
impl core::fmt::Display for ConstantTimeFailureKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
let detail = match self {
ConstantTimeFailureKind::LengthMismatch => "length mismatch",
ConstantTimeFailureKind::NotEqual => "not equal",
};
write!(f, "{detail}")
}
}
#[derive(Debug, Error, Clone, PartialEq, Eq)]
pub enum CryptoError {
#[error("invalid key material")]
InvalidKey,
#[error("invalid AEAD key length: expected {expected} bytes, got {actual} bytes")]
InvalidAeadKeyLength {
expected: usize,
actual: usize,
},
#[error("invalid AEAD nonce length: expected {expected} bytes, got {actual} bytes")]
InvalidAeadNonceLength {
expected: usize,
actual: usize,
},
#[error("invalid ciphertext length: minimum {minimum} bytes, got {actual} bytes")]
InvalidCiphertextLength {
minimum: usize,
actual: usize,
},
#[error("AEAD encryption failed in {backend} backend: {kind}")]
AeadEncrypt {
backend: AeadBackend,
kind: AeadFailureKind,
},
#[error("AEAD decryption failed in {backend} backend: {kind}")]
AeadDecrypt {
backend: AeadBackend,
kind: AeadFailureKind,
},
#[error("signature failed in {backend} backend during {operation}: {kind}")]
Signature {
backend: SignatureBackend,
operation: SignatureOperation,
kind: SignatureFailureKind,
},
#[error("key agreement failed: {kind}")]
KeyAgreementFailure {
kind: KeyAgreementFailureKind,
},
#[error("KEM operation failed: {kind}")]
KemFailure {
kind: KemFailureKind,
},
#[error("key wrap failed for {algorithm} during {operation}: {kind}")]
KeyWrap {
algorithm: KeyWrapAlgorithm,
operation: KeyWrapOperation,
kind: KeyWrapFailureKind,
},
#[error("KDF failed for {algorithm}/{profile}: {kind}")]
Kdf {
algorithm: KdfAlgorithm,
profile: KdfProfile,
kind: KdfFailureKind,
},
#[error("HKDF failed for {hash}: {kind}")]
Hkdf {
hash: HkdfHash,
kind: HkdfFailureKind,
},
#[error("HMAC failed for {hash}: {kind}")]
Mac {
hash: MacHash,
kind: MacFailureKind,
},
#[error("secure random generation failed for {output}: {kind}")]
Rng {
output: RngOutputKind,
kind: RngFailureKind,
},
#[error("constant-time comparison failed: {kind}")]
ConstantTimeComparison {
kind: ConstantTimeFailureKind,
left_len: usize,
right_len: usize,
},
#[error("unsupported operation")]
Unsupported,
}