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 //! Implementation of the `ICryptoOperationContext` AIDL interface. It can be used to execute more 18 //! commands over the same context. 19 20 use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::{ 21 CryptoOperation::CryptoOperation, ICryptoOperationContext::BnCryptoOperationContext, 22 ICryptoOperationContext::ICryptoOperationContext, 23 }; 24 use binder::binder_impl::Binder; 25 use hwcryptohal_common::{err::HwCryptoError, hwcrypto_err}; 26 use std::sync::Mutex; 27 28 use crate::cmd_processing::CmdProcessorContext; 29 30 /// The `ICryptoOperationContext` implementation. 31 pub struct CryptoOperationContext { 32 cmd_processor: Mutex<CmdProcessorContext>, 33 } 34 35 impl binder::Interface for CryptoOperationContext {} 36 37 impl CryptoOperationContext { new_binder( cmd_processor: CmdProcessorContext, ) -> binder::Strong<dyn ICryptoOperationContext>38 pub(crate) fn new_binder( 39 cmd_processor: CmdProcessorContext, 40 ) -> binder::Strong<dyn ICryptoOperationContext> { 41 let hwcrypto_key = CryptoOperationContext { cmd_processor: Mutex::new(cmd_processor) }; 42 BnCryptoOperationContext::new_binder(hwcrypto_key, binder::BinderFeatures::default()) 43 } 44 } 45 46 impl ICryptoOperationContext for CryptoOperationContext {} 47 48 pub(crate) struct BinderCryptoOperationContext(binder::Strong<dyn ICryptoOperationContext>); 49 50 impl From<binder::Strong<dyn ICryptoOperationContext>> for BinderCryptoOperationContext { from(value: binder::Strong<dyn ICryptoOperationContext>) -> Self51 fn from(value: binder::Strong<dyn ICryptoOperationContext>) -> Self { 52 Self(value) 53 } 54 } 55 56 impl From<BinderCryptoOperationContext> for binder::Strong<dyn ICryptoOperationContext> { from(value: BinderCryptoOperationContext) -> Self57 fn from(value: BinderCryptoOperationContext) -> Self { 58 value.0 59 } 60 } 61 62 impl BinderCryptoOperationContext { process_all_steps( &self, operations: &mut [CryptoOperation], ) -> Result<(), HwCryptoError>63 pub(crate) fn process_all_steps( 64 &self, 65 operations: &mut [CryptoOperation], 66 ) -> Result<(), HwCryptoError> { 67 let binder = self.0.as_binder(); 68 if binder.is_remote() { 69 return Err(hwcrypto_err!(GENERIC_ERROR, "binder is not local")); 70 } 71 let native_context: Binder<BnCryptoOperationContext> = binder.try_into().map_err(|e| { 72 hwcrypto_err!(GENERIC_ERROR, "shouldn't fail because binder is local {:?}", e) 73 })?; 74 let mut cmd_processor = native_context 75 .downcast_binder::<CryptoOperationContext>() 76 .ok_or(hwcrypto_err!(GENERIC_ERROR, "couldn't cast back operation context"))? 77 .cmd_processor 78 .lock() 79 .map_err(|e| { 80 hwcrypto_err!( 81 GENERIC_ERROR, 82 "poisoned mutex, shold not happen on a single thread application: {:?}", 83 e 84 ) 85 })?; 86 cmd_processor.process_all_steps(operations)?; 87 Ok(()) 88 } 89 } 90