dcrypt_pke/
error.rs

1//! Error handling for PKE operations.
2#![cfg_attr(not(feature = "std"), no_std)]
3
4use core::fmt;
5use dcrypt_algorithms::error::Error as PrimitiveError;
6use dcrypt_api::error::Error as CoreError;
7
8// Ensure String and format! are available for no_std + alloc
9#[cfg(all(not(feature = "std"), feature = "alloc"))]
10use alloc::format;
11#[cfg(all(not(feature = "std"), feature = "alloc"))]
12use alloc::string::{String, ToString};
13
14/// Error type for PKE operations.
15#[derive(Debug)]
16pub enum Error {
17    Primitive(PrimitiveError),
18    Api(CoreError),
19    InvalidCiphertextFormat(&'static str),
20    EncryptionFailed(&'static str),
21    DecryptionFailed(&'static str),
22    KeyDerivationFailed(&'static str),
23    UnsupportedOperation(&'static str),
24    SerializationError(&'static str),
25}
26
27impl fmt::Display for Error {
28    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29        match self {
30            Error::Primitive(e) => write!(f, "PKE primitive error: {}", e),
31            Error::Api(e) => write!(f, "PKE API error: {}", e),
32            Error::InvalidCiphertextFormat(reason) => {
33                write!(f, "Invalid PKE ciphertext format: {}", reason)
34            }
35            Error::EncryptionFailed(reason) => write!(f, "PKE encryption failed: {}", reason),
36            Error::DecryptionFailed(reason) => write!(f, "PKE decryption failed: {}", reason),
37            Error::KeyDerivationFailed(reason) => {
38                write!(f, "PKE key derivation failed: {}", reason)
39            }
40            Error::UnsupportedOperation(op) => write!(f, "PKE unsupported operation: {}", op),
41            Error::SerializationError(reason) => {
42                write!(f, "PKE internal serialization error: {}", reason)
43            }
44        }
45    }
46}
47
48#[cfg(feature = "std")]
49impl std::error::Error for Error {
50    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
51        match self {
52            Error::Primitive(e) => Some(e),
53            Error::Api(e) => Some(e),
54            _ => None,
55        }
56    }
57}
58
59impl From<PrimitiveError> for Error {
60    fn from(err: PrimitiveError) -> Self {
61        Error::Primitive(err)
62    }
63}
64
65impl From<CoreError> for Error {
66    fn from(err: CoreError) -> Self {
67        Error::Api(err)
68    }
69}
70
71// Conversion from PKE Error to API Error
72impl From<Error> for CoreError {
73    fn from(err: Error) -> Self {
74        match err {
75            Error::Primitive(e) => e.into(),
76            Error::Api(e) => e,
77            Error::InvalidCiphertextFormat(reason) => CoreError::InvalidCiphertext {
78                context: "ECIES",
79                #[cfg(feature = "std")]
80                message: reason.to_string(),
81            },
82            Error::EncryptionFailed(reason) => CoreError::Other {
83                context: "ECIES Encryption",
84                #[cfg(feature = "std")]
85                message: reason.to_string(),
86            },
87            Error::DecryptionFailed(reason) => {
88                // Provide more specific context for the AEAD-auth failure that
89                // the unit-tests look for, while keeping the generic string for
90                // every other reason.
91                let ctx: &'static str = if reason == "AEAD authentication failed" {
92                    "ECIES Decryption: AEAD authentication failed"
93                } else {
94                    "ECIES Decryption"
95                };
96                CoreError::DecryptionFailed {
97                    context: ctx,
98                    #[cfg(feature = "std")]
99                    message: reason.to_string(),
100                }
101            }
102            Error::KeyDerivationFailed(reason) => CoreError::Other {
103                context: "ECIES KDF",
104                #[cfg(feature = "std")]
105                message: reason.to_string(),
106            },
107            Error::UnsupportedOperation(op) => CoreError::NotImplemented { feature: op },
108            Error::SerializationError(reason) => CoreError::SerializationError {
109                context: "ECIES Internal",
110                #[cfg(feature = "std")]
111                message: reason.to_string(),
112            },
113        }
114    }
115}
116
117/// Result type for PKE operations.
118pub type Result<T> = core::result::Result<T, Error>;