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