blob: a69b2c36e4fd4931024b7099fe1deac017fd242c [file] [log] [blame]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//! AIDL IPC Server code.
use crate::hwcrypto_device_key;
use crate::hwcrypto_operations;
use alloc::rc::Rc;
use binder::SpIBinder;
use core::ffi::CStr;
use hwcryptohal_common::{err::HwCryptoError, hwcrypto_err};
use rpcbinder::RpcServer;
use tipc::{self, service_dispatcher, wrap_service, Manager, PortCfg, Uuid};
wrap_service!(HwCryptoDeviceKey(RpcServer: UnbufferedService));
wrap_service!(HwCryptoOperations(RpcServer: UnbufferedService));
service_dispatcher! {
enum HWCryptoHal {
HwCryptoOperations,
HwCryptoDeviceKey,
}
}
pub(crate) const RUST_HWCRYPTO_OPS_PORT: &CStr = c"com.android.trusty.rust.hwcryptohal.ops.V1";
pub(crate) const RUST_SERVICE_PORT: &CStr = c"com.android.trusty.rust.hwcryptohal.V1";
fn create_device_key_service(uuid: Uuid) -> Option<SpIBinder> {
Some(hwcrypto_device_key::HwCryptoKey::new_binder(uuid).as_binder())
}
pub fn main_loop() -> Result<(), HwCryptoError> {
let mut dispatcher = HWCryptoHal::<2>::new().map_err(|e| {
hwcrypto_err!(GENERIC_ERROR, "could not create multi-service dispatcher: {:?}", e)
})?;
let hw_key = hwcrypto_operations::HwCryptoOperations::new_binder();
let hwk_rpc_server = RpcServer::new(hw_key.as_binder());
let hwk_service = HwCryptoOperations(hwk_rpc_server);
let hwdk_rpc_server = RpcServer::new_per_session(create_device_key_service);
let hwdk_service = HwCryptoDeviceKey(hwdk_rpc_server);
let cfg =
PortCfg::new(RUST_HWCRYPTO_OPS_PORT.to_str().expect("should not happen, valid utf-8"))
.map_err(|e| {
hwcrypto_err!(
GENERIC_ERROR,
"could not create port config for {:?}: {:?}",
RUST_HWCRYPTO_OPS_PORT,
e
)
})?
.allow_ta_connect()
.allow_ns_connect();
dispatcher
.add_service(Rc::new(hwk_service), cfg)
.map_err(|e| hwcrypto_err!(GENERIC_ERROR, "could add HWCrypto service: {:?}", e))?;
let cfg = PortCfg::new(RUST_SERVICE_PORT.to_str().expect("should not happen, valid utf-8"))
.map_err(|e| {
hwcrypto_err!(
GENERIC_ERROR,
"could not create port config for {:?}: {:?}",
RUST_SERVICE_PORT,
e
)
})?
.allow_ta_connect()
.allow_ns_connect();
dispatcher.add_service(Rc::new(hwdk_service), cfg).map_err(|e| {
hwcrypto_err!(GENERIC_ERROR, "could add HWCrypto device key service: {:?}", e)
})?;
let manager = Manager::<_, _, 2, 4>::new_with_dispatcher(dispatcher, [])
.map_err(|e| hwcrypto_err!(GENERIC_ERROR, "could not create service manager: {:?}", e))?;
manager
.run_event_loop()
.map_err(|e| hwcrypto_err!(GENERIC_ERROR, "service manager received error: {:?}", e))
}
#[cfg(test)]
mod tests {
use android_hardware_security_see::aidl::android::hardware::security::see::hwcrypto::IHwCryptoKey::IHwCryptoKey;
use android_hardware_security_see::aidl::android::hardware::security::see::hwcrypto::IHwCryptoOperations::IHwCryptoOperations;
use rpcbinder::RpcSession;
use binder::{IBinder, Strong};
use test::expect_eq;
use super::*;
#[test]
fn connect_server() {
let session: Strong<dyn IHwCryptoOperations> = RpcSession::new()
.setup_trusty_client(RUST_HWCRYPTO_OPS_PORT)
.expect("Failed to connect");
expect_eq!(session.as_binder().ping_binder(), Ok(()));
let session_device_key: Strong<dyn IHwCryptoKey> =
RpcSession::new().setup_trusty_client(RUST_SERVICE_PORT).expect("Failed to connect");
expect_eq!(session_device_key.as_binder().ping_binder(), Ok(()));
}
}