| /* |
| * Copyright (C) 2024 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| //! HwCrypto error handling code and related structures |
| |
| use alloc::{collections::TryReserveError, ffi::CString}; |
| pub use android_hardware_security_see::aidl::android::hardware::security::see::hwcrypto::types::HalErrorCode; |
| use android_hardware_security_see::binder; |
| use core::array::TryFromSliceError; |
| use coset::CoseError; |
| use std::sync::PoisonError; |
| use tipc::TipcError; |
| use vm_memory::VolatileMemoryError; |
| |
| /// Macro used to create a `HwCryptoError::HalError` by providing the AIDL `HalErrorCode` and a |
| /// message: `hwcrypto_err!(UNSUPPORTED, "unsupported operation")` |
| #[macro_export] |
| macro_rules! hwcrypto_err { |
| { $error_code:ident, $($arg:tt)+ } => { |
| $crate::err::HwCryptoError::HalError { |
| code: $crate::err::HalErrorCode::$error_code, |
| file: std::file!(), |
| line: std::line!(), |
| message: alloc::format!("{}",std::format_args!($($arg)+)), |
| } |
| }; |
| } |
| |
| /// Base Error type for HwCrypto library. |
| #[derive(Debug)] |
| pub enum HwCryptoError { |
| /// HwCrypto library native error |
| HalError { code: i32, file: &'static str, line: u32, message: String }, |
| /// Error generated by a keymint library |
| KmError(kmr_common::Error), |
| /// Error when (de)serializing CBOR objects |
| CborError(kmr_wire::CborError), |
| } |
| |
| impl HwCryptoError { |
| pub fn matches_hal_error_code(&self, error_code: i32) -> bool { |
| core::matches!(self, HwCryptoError::HalError { code, .. } if *code == error_code) |
| } |
| } |
| |
| impl From<kmr_wire::CborError> for HwCryptoError { |
| fn from(e: kmr_wire::CborError) -> Self { |
| HwCryptoError::CborError(e) |
| } |
| } |
| |
| impl From<TipcError> for HwCryptoError { |
| fn from(e: TipcError) -> Self { |
| hwcrypto_err!(GENERIC_ERROR, "tipc communication error: {:?}", e) |
| } |
| } |
| |
| impl From<kmr_common::Error> for HwCryptoError { |
| fn from(e: kmr_common::Error) -> Self { |
| HwCryptoError::KmError(e) |
| } |
| } |
| |
| impl From<CoseError> for HwCryptoError { |
| fn from(e: CoseError) -> Self { |
| hwcrypto_err!(SERIALIZATION_ERROR, "Deserialization error: {}", e) |
| } |
| } |
| |
| impl From<TryReserveError> for HwCryptoError { |
| fn from(e: TryReserveError) -> Self { |
| hwcrypto_err!(ALLOCATION_ERROR, "error allocating: {}", e) |
| } |
| } |
| |
| impl From<VolatileMemoryError> for HwCryptoError { |
| fn from(e: VolatileMemoryError) -> Self { |
| hwcrypto_err!(BAD_PARAMETER, "memory buffer slice error: {}", e) |
| } |
| } |
| |
| impl From<TryFromSliceError> for HwCryptoError { |
| fn from(e: TryFromSliceError) -> Self { |
| hwcrypto_err!(ALLOCATION_ERROR, "error allocating from slice: {}", e) |
| } |
| } |
| |
| impl From<HwCryptoError> for binder::Status { |
| fn from(e: HwCryptoError) -> Self { |
| match e { |
| HwCryptoError::KmError(e) => { |
| let msg = CString::new(format!("KM error {:?}", e).as_str()).unwrap(); |
| binder::Status::new_service_specific_error(HalErrorCode::GENERIC_ERROR, Some(&msg)) |
| } |
| HwCryptoError::HalError { code, file, line, message } => { |
| let msg = CString::new( |
| format!("HWCrypto error on {}:{}: {}", file, line, message).as_str(), |
| ) |
| .unwrap(); |
| binder::Status::new_service_specific_error(code, Some(&msg)) |
| } |
| HwCryptoError::CborError(e) => { |
| let msg = |
| CString::new(format!("CBOR serialization error {:?}", e).as_str()).unwrap(); |
| binder::Status::new_service_specific_error( |
| HalErrorCode::SERIALIZATION_ERROR, |
| Some(&msg), |
| ) |
| } |
| } |
| } |
| } |
| |
| impl<T> From<PoisonError<T>> for HwCryptoError { |
| fn from(_: PoisonError<T>) -> Self { |
| hwcrypto_err!( |
| GENERIC_ERROR, |
| "found PoisonError which shouldn't happen, we are single threaded" |
| ) |
| } |
| } |