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}