Skip to main content

oxicrypto_core/
error.rs

1/// Unified error type for all OxiCrypto operations.
2#[derive(Debug, Clone, PartialEq, Eq)]
3pub enum CryptoError {
4    /// Supplied key has wrong length or is otherwise invalid.
5    InvalidKey,
6    /// Supplied nonce/IV has wrong length or is otherwise invalid.
7    InvalidNonce,
8    /// Authentication tag verification failed (AEAD open / MAC verify).
9    InvalidTag,
10    /// Output buffer is too small for the requested operation.
11    BufferTooSmall,
12    /// General bad-input condition (e.g. zero-length KDF output requested).
13    BadInput,
14    /// An internal or backend error with a static message.
15    Internal(&'static str),
16    /// Key-exchange or encapsulation/decapsulation failure (e.g. ML-KEM).
17    Kex,
18    /// Signature generation or verification failure (e.g. ML-DSA).
19    Sign,
20    /// RNG-specific failure (e.g. `getrandom` unavailable).
21    Rng,
22    /// Encoding / decoding failure (DER, PEM, SEC1, etc.).
23    Encoding,
24    /// Requested algorithm is not compiled-in or not supported at runtime.
25    UnsupportedAlgorithm,
26}
27
28impl core::fmt::Display for CryptoError {
29    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
30        match self {
31            CryptoError::InvalidKey => write!(f, "invalid key"),
32            CryptoError::InvalidNonce => write!(f, "invalid nonce"),
33            CryptoError::InvalidTag => write!(f, "invalid authentication tag"),
34            CryptoError::BufferTooSmall => write!(f, "output buffer too small"),
35            CryptoError::BadInput => write!(f, "bad input"),
36            CryptoError::Internal(msg) => write!(f, "internal error: {msg}"),
37            CryptoError::Kex => write!(f, "key exchange or encapsulation failure"),
38            CryptoError::Sign => write!(f, "signature generation or verification failure"),
39            CryptoError::Rng => write!(f, "random number generator failure"),
40            CryptoError::Encoding => write!(f, "encoding or decoding failure"),
41            CryptoError::UnsupportedAlgorithm => write!(f, "unsupported algorithm"),
42        }
43    }
44}
45
46// `core::error::Error` is stable since Rust 1.81; implement it unconditionally
47// so that `CryptoError` satisfies bounds like `rand_core::TryRng::Error`
48// which require `core::error::Error` regardless of the `std` feature.
49// Note: `std::error::Error` re-exports `core::error::Error` in Rust 1.81+,
50// so we only implement it once here rather than separately for each gate.
51impl core::error::Error for CryptoError {}
52
53#[cfg(feature = "std")]
54extern crate std;
55
56#[cfg(feature = "std")]
57impl From<CryptoError> for std::io::Error {
58    fn from(e: CryptoError) -> Self {
59        std::io::Error::other(alloc::format!("{e}"))
60    }
61}