1 /* 2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //! HwCrypto error handling code and related structures 18 19 use alloc::{collections::TryReserveError, ffi::CString}; 20 pub use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::types::HalErrorCode; 21 use android_hardware_security_see_hwcrypto::binder; 22 use core::array::TryFromSliceError; 23 use coset::CoseError; 24 use std::sync::PoisonError; 25 use tipc::TipcError; 26 use vm_memory::VolatileMemoryError; 27 28 /// Macro used to create a `HwCryptoError::HalError` by providing the AIDL `HalErrorCode` and a 29 /// message: `hwcrypto_err!(UNSUPPORTED, "unsupported operation")` 30 #[macro_export] 31 macro_rules! hwcrypto_err { 32 { $error_code:ident, $($arg:tt)+ } => { 33 $crate::err::HwCryptoError::HalError { 34 code: $crate::err::HalErrorCode::$error_code, 35 file: std::file!(), 36 line: std::line!(), 37 message: alloc::format!("{}",std::format_args!($($arg)+)), 38 } 39 }; 40 } 41 42 /// Base Error type for HwCrypto library. 43 #[derive(Debug)] 44 pub enum HwCryptoError { 45 /// HwCrypto library native error 46 HalError { code: i32, file: &'static str, line: u32, message: String }, 47 /// Error generated by a keymint library 48 KmError(kmr_common::Error), 49 /// Error when (de)serializing CBOR objects 50 CborError(kmr_wire::CborError), 51 } 52 53 impl HwCryptoError { matches_hal_error_code(&self, error_code: i32) -> bool54 pub fn matches_hal_error_code(&self, error_code: i32) -> bool { 55 core::matches!(self, HwCryptoError::HalError { code, .. } if *code == error_code) 56 } 57 } 58 59 impl From<kmr_wire::CborError> for HwCryptoError { from(e: kmr_wire::CborError) -> Self60 fn from(e: kmr_wire::CborError) -> Self { 61 HwCryptoError::CborError(e) 62 } 63 } 64 65 impl From<TipcError> for HwCryptoError { from(e: TipcError) -> Self66 fn from(e: TipcError) -> Self { 67 hwcrypto_err!(GENERIC_ERROR, "tipc communication error: {:?}", e) 68 } 69 } 70 71 impl From<kmr_common::Error> for HwCryptoError { from(e: kmr_common::Error) -> Self72 fn from(e: kmr_common::Error) -> Self { 73 HwCryptoError::KmError(e) 74 } 75 } 76 77 impl From<CoseError> for HwCryptoError { from(e: CoseError) -> Self78 fn from(e: CoseError) -> Self { 79 hwcrypto_err!(SERIALIZATION_ERROR, "Deserialization error: {}", e) 80 } 81 } 82 83 impl From<TryReserveError> for HwCryptoError { from(e: TryReserveError) -> Self84 fn from(e: TryReserveError) -> Self { 85 hwcrypto_err!(ALLOCATION_ERROR, "error allocating: {}", e) 86 } 87 } 88 89 impl From<VolatileMemoryError> for HwCryptoError { from(e: VolatileMemoryError) -> Self90 fn from(e: VolatileMemoryError) -> Self { 91 hwcrypto_err!(BAD_PARAMETER, "memory buffer slice error: {}", e) 92 } 93 } 94 95 impl From<TryFromSliceError> for HwCryptoError { from(e: TryFromSliceError) -> Self96 fn from(e: TryFromSliceError) -> Self { 97 hwcrypto_err!(ALLOCATION_ERROR, "error allocating from slice: {}", e) 98 } 99 } 100 101 impl From<HwCryptoError> for binder::Status { from(e: HwCryptoError) -> Self102 fn from(e: HwCryptoError) -> Self { 103 match e { 104 HwCryptoError::KmError(e) => { 105 let msg = CString::new(format!("KM error {:?}", e).as_str()).unwrap(); 106 binder::Status::new_service_specific_error(HalErrorCode::GENERIC_ERROR, Some(&msg)) 107 } 108 HwCryptoError::HalError { code, file, line, message } => { 109 let msg = CString::new( 110 format!("HWCrypto error on {}:{}: {}", file, line, message).as_str(), 111 ) 112 .unwrap(); 113 binder::Status::new_service_specific_error(code, Some(&msg)) 114 } 115 HwCryptoError::CborError(e) => { 116 let msg = 117 CString::new(format!("CBOR serialization error {:?}", e).as_str()).unwrap(); 118 binder::Status::new_service_specific_error( 119 HalErrorCode::SERIALIZATION_ERROR, 120 Some(&msg), 121 ) 122 } 123 } 124 } 125 } 126 127 impl<T> From<PoisonError<T>> for HwCryptoError { from(_: PoisonError<T>) -> Self128 fn from(_: PoisonError<T>) -> Self { 129 hwcrypto_err!( 130 GENERIC_ERROR, 131 "found PoisonError which shouldn't happen, we are single threaded" 132 ) 133 } 134 } 135