Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88676076 authored by David Drysdale's avatar David Drysdale Committed by Gerrit Code Review
Browse files

Merge "Initial Secretkeeper HAL service for Trusty" into main

parents d95213e7 8e1c267c
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
//
// Copyright (C) 2022 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.

package {
    default_applicable_licenses: ["Android-Apache-2.0"],
}

rust_binary {
    name: "android.hardware.security.secretkeeper.trusty",
    relative_install_path: "hw",
    vendor: true,
    init_rc: ["android.hardware.security.secretkeeper.trusty.rc"],
    vintf_fragments: ["android.hardware.security.secretkeeper.trusty.xml"],
    srcs: [
        "src/hal_main.rs",
    ],
    rustlibs: [
        "libandroid_logger",
        "libbinder_rs",
        "libauthgraph_hal",
        "libtrusty-rs",
        "liblibc",
        "liblog_rust",
        "libsecretkeeper_hal",
    ],
    defaults: [
        "secretkeeper_use_latest_hal_aidl_rust",
    ],
    prefer_rlib: true,
}
+4 −0
Original line number Diff line number Diff line
service vendor.secretkeeper.trusty /vendor/bin/hw/android.hardware.security.secretkeeper.trusty
    class hal
    user nobody
    group drmrpc
 No newline at end of file
+7 −0
Original line number Diff line number Diff line
<manifest version="1.0" type="device">
    <hal format="aidl">
        <name>android.hardware.security.secretkeeper</name>
        <version>1</version>
        <fqname>ISecretkeeper/default</fqname>
    </hal>
</manifest>
+141 −0
Original line number Diff line number Diff line
//
// Copyright (C) 2022 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.

//! This module implements the HAL service for Secretkeeper in Trusty.
use authgraph_hal::{channel::SerializedChannel};
use secretkeeper_hal::SecretkeeperService;
use android_hardware_security_secretkeeper::aidl::android::hardware::security::secretkeeper::ISecretkeeper::{
    ISecretkeeper, BpSecretkeeper,
};
use log::{error, info};
use std::{
    ffi::CString,
    panic,
    sync::{Arc, Mutex},
};
use trusty::DEFAULT_DEVICE;

const SK_TIPC_SERVICE_PORT: &str = "com.android.trusty.secretkeeper";
const AG_TIPC_SERVICE_PORT: &str = "com.android.trusty.secretkeeper.authgraph";

static SERVICE_INSTANCE: &str = "default";

/// Local error type for failures in the HAL service.
#[derive(Debug, Clone)]
struct HalServiceError(String);

#[derive(Debug)]
struct TipcChannel {
    channel: Arc<Mutex<trusty::TipcChannel>>,
}

impl TipcChannel {
    fn new(channel: trusty::TipcChannel) -> Self {
        Self { channel: Arc::new(Mutex::new(channel)) }
    }
}

impl SerializedChannel for TipcChannel {
    const MAX_SIZE: usize = 4000;
    fn execute(&self, req_data: &[u8]) -> binder::Result<Vec<u8>> {
        // Hold lock across both request and response.
        let mut channel = self.channel.lock().unwrap();
        channel.send(req_data).map_err(|e| {
            binder::Status::new_exception(
                binder::ExceptionCode::TRANSACTION_FAILED,
                Some(
                    &CString::new(format!(
                        "Failed to send the request via tipc channel because of {:?}",
                        e
                    ))
                    .unwrap(),
                ),
            )
        })?;
        // TODO: cope with fragmentation and reassembly
        let mut rsp_data = Vec::new();
        channel.recv(&mut rsp_data).map_err(|e| {
            binder::Status::new_exception(
                binder::ExceptionCode::TRANSACTION_FAILED,
                Some(
                    &CString::new(format!(
                        "Failed to receive the response via tipc channel because of {:?}",
                        e
                    ))
                    .unwrap(),
                ),
            )
        })?;
        Ok(rsp_data)
    }
}

fn main() {
    if let Err(e) = inner_main() {
        panic!("HAL service failed: {:?}", e);
    }
}

fn inner_main() -> Result<(), HalServiceError> {
    // Initialize Android logging.
    android_logger::init_once(
        android_logger::Config::default()
            .with_tag("secretkeeper-hal-trusty")
            .with_min_level(log::Level::Info)
            .with_log_id(android_logger::LogId::System),
    );
    // Redirect panic messages to logcat.
    panic::set_hook(Box::new(|panic_info| {
        error!("{}", panic_info);
    }));

    info!("Trusty Secretkeeper HAL service is starting.");

    info!("Starting thread pool now.");
    binder::ProcessState::start_thread_pool();

    // Create connections to the TA.
    let ag_connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, AG_TIPC_SERVICE_PORT)
        .map_err(|e| {
            HalServiceError(format!(
                "Failed to connect to Trusty port {AG_TIPC_SERVICE_PORT} because of {:?}.",
                e
            ))
        })?;
    let ag_tipc_channel = TipcChannel::new(ag_connection);

    let sk_connection = trusty::TipcChannel::connect(DEFAULT_DEVICE, SK_TIPC_SERVICE_PORT)
        .map_err(|e| {
            HalServiceError(format!(
                "Failed to connect to Trusty port {SK_TIPC_SERVICE_PORT} because of {:?}.",
                e
            ))
        })?;
    let sk_tipc_channel = TipcChannel::new(sk_connection);

    // Register the AIDL service
    let service = SecretkeeperService::new_as_binder(sk_tipc_channel, ag_tipc_channel);
    let service_name =
        format!("{}/{}", <BpSecretkeeper as ISecretkeeper>::get_descriptor(), SERVICE_INSTANCE);
    binder::add_service(&service_name, service.as_binder()).map_err(|e| {
        HalServiceError(format!("Failed to register service {} because of {:?}.", service_name, e))
    })?;

    info!("Successfully registered Secretkeeper HAL service.");
    info!("Joining thread pool now.");
    binder::ProcessState::join_thread_pool();
    info!("Secretkeeper HAL service is terminating."); // should not reach here
    Ok(())
}
+8 −0
Original line number Diff line number Diff line
@@ -35,8 +35,16 @@ else
    LOCAL_KEYMINT_PRODUCT_PACKAGE := android.hardware.security.keymint-service.trusty
endif

# TODO(b/306364873): move this to be flag-controlled?
ifeq ($(SECRETKEEPER_ENABLED),)
    LOCAL_SECRETKEEPER_PRODUCT_PACKAGE :=
else
    LOCAL_SECRETKEEPER_PRODUCT_PACKAGE := android.hardware.security.secretkeeper.trusty
endif

PRODUCT_PACKAGES += \
	$(LOCAL_KEYMINT_PRODUCT_PACKAGE) \
	$(LOCAL_SECRETKEEPER_PRODUCT_PACKAGE) \
	android.hardware.gatekeeper-service.trusty \
	trusty_apploader \