blob: 1739c94ab50b7dbab64f4948490f53fa3e2bf7be [file] [log] [blame]
/*
* 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"
)
}
}