use core::fmt;
pub(crate) const WH_ERROR_MIN: i32 = -2302;
pub(crate) const WH_ERROR_MAX: i32 = -2000;
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Error {
Wh {
code: i32,
},
Ffi {
code: i32,
func: &'static str,
},
AlreadyRegistered,
InvalidInput {
msg: &'static str,
},
DataLost {
id: u16,
},
ProtocolError {
msg: &'static str,
},
SignatureInvalid,
}
impl Error {
#[inline]
pub fn check(rc: i32, func: &'static str) -> Result<(), Error> {
if rc == 0 {
Ok(())
} else if (WH_ERROR_MIN..=WH_ERROR_MAX).contains(&rc) {
Err(Error::Wh { code: rc })
} else {
Err(Error::Ffi { code: rc, func })
}
}
}
fn wh_error_name(code: i32) -> Option<&'static str> {
match code {
-2000 => Some("WH_ERROR_BADARGS"),
-2001 => Some("WH_ERROR_NOTREADY"),
-2002 => Some("WH_ERROR_ABORTED"),
-2003 => Some("WH_ERROR_RESERVED1"),
-2004 => Some("WH_ERROR_RESERVED2"),
-2005 => Some("WH_ERROR_CERT_VERIFY"),
-2006 => Some("WH_ERROR_BUFFER_SIZE"),
-2007 => Some("WH_ERROR_NOHANDLER"),
-2008 => Some("WH_ERROR_NOTIMPL"),
-2009 => Some("WH_ERROR_USAGE"),
-2010 => Some("WH_ERROR_TIMEOUT"),
-2011 => Some("WH_ERROR_REQUEST_PENDING"),
-2100 => Some("WH_ERROR_LOCKED"),
-2101 => Some("WH_ERROR_ACCESS"),
-2102 => Some("WH_ERROR_NOTVERIFIED"),
-2103 => Some("WH_ERROR_NOTBLANK"),
-2104 => Some("WH_ERROR_NOTFOUND"),
-2105 => Some("WH_ERROR_NOSPACE"),
-2200 => Some("WH_SHE_ERC_SEQUENCE_ERROR"),
-2201 => Some("WH_SHE_ERC_KEY_NOT_AVAILABLE"),
-2202 => Some("WH_SHE_ERC_KEY_INVALID"),
-2203 => Some("WH_SHE_ERC_KEY_EMPTY"),
-2204 => Some("WH_SHE_ERC_NO_SECURE_BOOT"),
-2205 => Some("WH_SHE_ERC_WRITE_PROTECTED"),
-2206 => Some("WH_SHE_ERC_KEY_UPDATE_ERROR"),
-2207 => Some("WH_SHE_ERC_RNG_SEED"),
-2208 => Some("WH_SHE_ERC_NO_DEBUGGING"),
-2209 => Some("WH_SHE_ERC_BUSY"),
-2210 => Some("WH_SHE_ERC_MEMORY_FAILURE"),
-2211 => Some("WH_SHE_ERC_GENERAL_ERROR"),
-2300 => Some("WH_AUTH_LOGIN_FAILED"),
-2301 => Some("WH_AUTH_PERMISSION_ERROR"),
-2302 => Some("WH_AUTH_NOT_ENABLED"),
_ => None,
}
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Error::Wh { code } => {
if let Some(name) = wh_error_name(*code) {
write!(f, "wolfHSM error {code} ({name})")
} else {
write!(f, "wolfHSM error {code} (see wolfhsm/wh_error.h)")
}
}
Error::Ffi { code, func } => {
write!(f, "{func} failed: wolfSSL FFI error {code}")
}
Error::AlreadyRegistered => {
write!(
f,
"wolfHSM CryptoCb already registered; drop the existing guard first"
)
}
Error::InvalidInput { msg } => write!(f, "invalid argument: {msg}"),
Error::DataLost { id } => {
write!(
f,
"wolfHSM NVM object {id} deleted but add failed; original data lost"
)
}
Error::ProtocolError { msg } => {
write!(f, "wolfHSM protocol error: {msg}")
}
Error::SignatureInvalid => {
write!(f, "wolfHSM: signature or MAC verification failed")
}
}
}
}
impl core::error::Error for Error {}