dcrypt_algorithms/error/
mod.rs

1//! Error handling for cryptographic primitives
2
3#![cfg_attr(not(feature = "std"), no_std)]
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8#[cfg(feature = "alloc")]
9use alloc::borrow::Cow;
10
11#[cfg(feature = "std")]
12use std::fmt;
13
14#[cfg(not(feature = "std"))]
15use core::fmt;
16
17use dcrypt_api::{Error as CoreError, Result as CoreResult};
18
19/// The error type for cryptographic primitives
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub enum Error {
22    /// Parameter validation error
23    Parameter {
24        /// Name of the invalid parameter
25        name: Cow<'static, str>, // Changed from &'static str
26        /// Reason why the parameter is invalid
27        reason: Cow<'static, str>, // Changed from &'static str
28    },
29
30    /// Length validation error
31    Length {
32        /// Context where the length error occurred
33        context: &'static str,
34        /// Expected length in bytes
35        expected: usize,
36        /// Actual length in bytes
37        actual: usize,
38    },
39
40    /// Authentication failure (e.g., AEAD tag verification)
41    Authentication {
42        /// Algorithm that failed authentication
43        algorithm: &'static str,
44    },
45
46    /// Feature not implemented
47    NotImplemented {
48        /// Name of the unimplemented feature
49        feature: &'static str,
50    },
51
52    /// Processing error during cryptographic operation
53    Processing {
54        /// Operation that failed
55        operation: &'static str,
56        /// Additional details about the failure
57        details: &'static str,
58    },
59
60    /// MAC error
61    MacError {
62        /// MAC algorithm that encountered the error
63        algorithm: &'static str,
64        /// Additional details about the MAC error
65        details: &'static str,
66    },
67
68    /// External errors with String details (only available with alloc/std)
69    #[cfg(feature = "std")]
70    External {
71        /// Source of the external error
72        source: &'static str,
73        /// Detailed error message
74        details: String,
75    },
76
77    #[cfg(not(feature = "std"))]
78    External {
79        /// Source of the external error
80        source: &'static str,
81    },
82
83    /// Fallback for other errors
84    Other(&'static str),
85}
86
87// Add convenience helper
88impl Error {
89    /// Shorthand to create a Parameter error
90    pub fn param<N: Into<Cow<'static, str>>, R: Into<Cow<'static, str>>>(
91        name: N,
92        reason: R,
93    ) -> Self {
94        Error::Parameter {
95            name: name.into(),
96            reason: reason.into(),
97        }
98    }
99}
100
101/// Result type for cryptographic primitives operations
102pub type Result<T> = core::result::Result<T, Error>;
103
104// Specialized result types for different cryptographic operations
105/// Result type for cipher operations
106pub type CipherResult<T> = Result<T>;
107/// Result type for hash operations
108pub type HashResult<T> = Result<T>;
109/// Result type for MAC operations
110pub type MacResult<T> = Result<T>;
111
112// Display implementation for error formatting
113impl fmt::Display for Error {
114    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115        match self {
116            Error::Parameter { name, reason } => {
117                write!(f, "Invalid parameter '{}': {}", name, reason)
118            }
119            Error::Length {
120                context,
121                expected,
122                actual,
123            } => {
124                write!(
125                    f,
126                    "Invalid length for {}: expected {}, got {}",
127                    context, expected, actual
128                )
129            }
130            Error::Authentication { algorithm } => {
131                write!(f, "Authentication failed for {}", algorithm)
132            }
133            Error::NotImplemented { feature } => {
134                write!(f, "Feature not implemented: {}", feature)
135            }
136            Error::Processing { operation, details } => {
137                write!(f, "Processing error in {}: {}", operation, details)
138            }
139            Error::MacError { algorithm, details } => {
140                write!(f, "MAC error in {}: {}", algorithm, details)
141            }
142            #[cfg(feature = "std")]
143            Error::External { source, details } => {
144                write!(f, "External error from {}: {}", source, details)
145            }
146            #[cfg(not(feature = "std"))]
147            Error::External { source } => {
148                write!(f, "External error from {}", source)
149            }
150            Error::Other(msg) => write!(f, "{}", msg),
151        }
152    }
153}
154
155// Implement std::error::Error when std is available
156#[cfg(feature = "std")]
157impl std::error::Error for Error {}
158
159// Implement conversion to CoreError
160impl From<Error> for CoreError {
161    fn from(err: Error) -> Self {
162        match err {
163            Error::Parameter { name, reason } => CoreError::InvalidParameter {
164                context: match name {
165                    Cow::Borrowed(s) => s,
166                    Cow::Owned(s) => Box::leak(s.into_boxed_str()),
167                },
168                #[cfg(feature = "std")]
169                message: reason.into_owned(),
170            },
171            Error::Length {
172                context,
173                expected,
174                actual,
175            } => CoreError::InvalidLength {
176                context,
177                expected,
178                actual,
179            },
180            Error::Authentication { algorithm } => CoreError::AuthenticationFailed {
181                context: algorithm,
182                #[cfg(feature = "std")]
183                message: "authentication failed".to_string(),
184            },
185            Error::NotImplemented { feature } => CoreError::NotImplemented { feature },
186            Error::Processing { operation, details } => CoreError::Other {
187                context: operation,
188                #[cfg(feature = "std")]
189                message: details.to_string(),
190            },
191            Error::MacError { algorithm, details } => CoreError::Other {
192                context: algorithm,
193                #[cfg(feature = "std")]
194                message: details.to_string(),
195            },
196            #[cfg(feature = "std")]
197            Error::External { source, details } => CoreError::Other {
198                context: source,
199                message: details,
200            },
201            #[cfg(not(feature = "std"))]
202            Error::External { source } => CoreError::Other {
203                context: source,
204                #[cfg(feature = "std")]
205                message: "external error".to_string(),
206            },
207            Error::Other(msg) => CoreError::Other {
208                context: "primitives",
209                #[cfg(feature = "std")]
210                message: msg.to_string(),
211            },
212        }
213    }
214}
215
216/// Convert a primitives result to a core result with additional context
217#[inline]
218pub fn to_core_result<T>(r: Result<T>, ctx: &'static str) -> CoreResult<T> {
219    r.map_err(|e| {
220        let mut core = CoreError::from(e);
221        core = core.with_context(ctx);
222        core
223    })
224}
225
226// Re-export core error handling traits for convenience
227pub use dcrypt_api::error::{ResultExt, SecureErrorHandling};
228
229// Include the validation submodule
230pub mod validate;