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