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 //! AIDL IPC Server code.
18 use crate::hwcrypto_device_key;
19 use crate::hwcrypto_operations;
20 use alloc::rc::Rc;
21 use binder::SpIBinder;
22 use core::ffi::CStr;
23 use hwcryptohal_common::{err::HwCryptoError, hwcrypto_err};
24 use rpcbinder::RpcServer;
25 use tipc::{self, service_dispatcher, wrap_service, Manager, PortCfg, Uuid};
26 
27 wrap_service!(HwCryptoDeviceKey(RpcServer: UnbufferedService));
28 wrap_service!(HwCryptoOperations(RpcServer: UnbufferedService));
29 
30 service_dispatcher! {
31     enum HWCryptoHal {
32         HwCryptoOperations,
33         HwCryptoDeviceKey,
34     }
35 }
36 
37 pub(crate) const RUST_HWCRYPTO_OPS_PORT: &CStr = c"com.android.trusty.rust.hwcryptohal.ops.V1";
38 pub(crate) const RUST_SERVICE_PORT: &CStr = c"com.android.trusty.rust.hwcryptohal.V1";
39 
create_device_key_service(uuid: Uuid) -> Option<SpIBinder>40 fn create_device_key_service(uuid: Uuid) -> Option<SpIBinder> {
41     Some(hwcrypto_device_key::HwCryptoKey::new_binder(uuid).as_binder())
42 }
43 
main_loop() -> Result<(), HwCryptoError>44 pub fn main_loop() -> Result<(), HwCryptoError> {
45     let mut dispatcher = HWCryptoHal::<2>::new().map_err(|e| {
46         hwcrypto_err!(GENERIC_ERROR, "could not create multi-service dispatcher: {:?}", e)
47     })?;
48 
49     let hw_key = hwcrypto_operations::HwCryptoOperations::new_binder();
50     let hwk_rpc_server = RpcServer::new(hw_key.as_binder());
51     let hwk_service = HwCryptoOperations(hwk_rpc_server);
52     let hwdk_rpc_server = RpcServer::new_per_session(create_device_key_service);
53     let hwdk_service = HwCryptoDeviceKey(hwdk_rpc_server);
54 
55     let cfg =
56         PortCfg::new(RUST_HWCRYPTO_OPS_PORT.to_str().expect("should not happen, valid utf-8"))
57             .map_err(|e| {
58                 hwcrypto_err!(
59                     GENERIC_ERROR,
60                     "could not create port config for {:?}: {:?}",
61                     RUST_HWCRYPTO_OPS_PORT,
62                     e
63                 )
64             })?
65             .allow_ta_connect()
66             .allow_ns_connect();
67 
68     dispatcher
69         .add_service(Rc::new(hwk_service), cfg)
70         .map_err(|e| hwcrypto_err!(GENERIC_ERROR, "could add HWCrypto service: {:?}", e))?;
71 
72     let cfg = PortCfg::new(RUST_SERVICE_PORT.to_str().expect("should not happen, valid utf-8"))
73         .map_err(|e| {
74             hwcrypto_err!(
75                 GENERIC_ERROR,
76                 "could not create port config for {:?}: {:?}",
77                 RUST_SERVICE_PORT,
78                 e
79             )
80         })?
81         .allow_ta_connect()
82         .allow_ns_connect();
83 
84     dispatcher.add_service(Rc::new(hwdk_service), cfg).map_err(|e| {
85         hwcrypto_err!(GENERIC_ERROR, "could add HWCrypto device key service: {:?}", e)
86     })?;
87 
88     let manager = Manager::<_, _, 2, 4>::new_with_dispatcher(dispatcher, [])
89         .map_err(|e| hwcrypto_err!(GENERIC_ERROR, "could not create service manager: {:?}", e))?;
90 
91     manager
92         .run_event_loop()
93         .map_err(|e| hwcrypto_err!(GENERIC_ERROR, "service manager received error: {:?}", e))
94 }
95 
96 #[cfg(test)]
97 mod tests {
98     use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::IHwCryptoKey;
99     use android_hardware_security_see_hwcrypto::aidl::android::hardware::security::see::hwcrypto::IHwCryptoOperations::IHwCryptoOperations;
100     use rpcbinder::RpcSession;
101     use binder::{IBinder, Strong};
102     use test::expect_eq;
103     use super::*;
104 
105     #[test]
connect_server()106     fn connect_server() {
107         let session: Strong<dyn IHwCryptoOperations> = RpcSession::new()
108             .setup_trusty_client(RUST_HWCRYPTO_OPS_PORT)
109             .expect("Failed to connect");
110         expect_eq!(session.as_binder().ping_binder(), Ok(()));
111 
112         let session_device_key: Strong<dyn IHwCryptoKey> =
113             RpcSession::new().setup_trusty_client(RUST_SERVICE_PORT).expect("Failed to connect");
114         expect_eq!(session_device_key.as_binder().ping_binder(), Ok(()));
115     }
116 }
117