/*
 * 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.
 */
//! Trusty handler for IPC connections. It handles both secure and non-secure world ports.
use crate::secure_storage_manager;
use alloc::{rc::Rc, vec::Vec};
use core::{cell::RefCell, mem};
use keymint_access_policy::{
    keymint_check_secure_target_access_policy_provisioning, keymint_check_target_access_policy,
};
use kmr_common::{
    crypto, km_err,
    wire::legacy::{
        self, AppendAttestationCertChainResponse, AppendUdsCertificateResponse,
        ClearAttestationCertChainResponse, ClearUdsCertificateResponse,
        ConfigureBootPatchlevelResponse, GetAuthTokenKeyResponse, GetDeviceInfoResponse,
        GetVersion2Response, GetVersionResponse, SetAttestationIdsKM3Response,
        SetAttestationIdsResponse, SetAttestationKeyResponse, SetBootParamsResponse,
        SetWrappedAttestationKeyResponse, TrustyMessageId, TrustyPerformOpReq, TrustyPerformOpRsp,
        TrustyPerformSecureOpReq, TrustyPerformSecureOpRsp,
    },
    Error,
};
use kmr_ta::{self, device::SigningAlgorithm, split_rsp, HardwareInfo, KeyMintTa, RpcInfo};
use kmr_wire::keymint::{Algorithm, BootInfo};
use log::{debug, error, info};
use system_state::{ProvisioningAllowedFlagValues, SystemState, SystemStateFlag};
use tipc::{
    service_dispatcher, ConnectResult, Deserialize, Handle, Manager, MessageResult, PortCfg,
    Serialize, Serializer, Service, TipcError, Uuid,
};
use trusty_std::alloc::TryAllocFrom;

/// Port that handles new style keymint messages from non-secure world
const KM_NS_TIPC_SRV_PORT: &str = "com.android.trusty.keymint";
/// Port that handles secure world messages
const KM_SEC_TIPC_SRV_PORT: &str = "com.android.trusty.keymaster.secure";
/// Port that handles legacy style keymint/keymaster messages
const KM_NS_LEGACY_TIPC_SRV_PORT: &str = "com.android.trusty.keymaster";
/// Port count for this TA (as above).
const PORT_COUNT: usize = 3;
/// Maximum connection count for this TA:
/// - Gatekeeper
/// - Fingerprint
/// - FaceAuth
/// - Widevine
/// - Non-secure world.
const MAX_CONNECTION_COUNT: usize = 5;

const KEYMINT_MAX_BUFFER_LENGTH: usize = 4096;
const KEYMINT_MAX_MESSAGE_CONTENT_SIZE: usize = 4000;

/// TIPC connection context information.
struct Context {
    uuid: Uuid,
}

/// Newtype wrapper for opaque messages.
struct KMMessage(Vec<u8>);

impl Deserialize for KMMessage {
    type Error = TipcError;
    const MAX_SERIALIZED_SIZE: usize = KEYMINT_MAX_BUFFER_LENGTH;

    fn deserialize(bytes: &[u8], _handles: &mut [Option<Handle>]) -> tipc::Result<Self> {
        Ok(KMMessage(Vec::try_alloc_from(bytes)?))
    }
}

impl<'s> Serialize<'s> for KMMessage {
    fn serialize<'a: 's, S: Serializer<'s>>(
        &'a self,
        serializer: &mut S,
    ) -> Result<S::Ok, S::Error> {
        serializer.serialize_bytes(self.0.as_slice())
    }
}

/// Convert KeyMint [`Algorithm`] to [`SigningAlgorithm`].
fn keymaster_algorithm_to_signing_algorithm(
    algorithm: Algorithm,
) -> Result<SigningAlgorithm, Error> {
    match algorithm {
        Algorithm::Rsa => Ok(SigningAlgorithm::Rsa),
        Algorithm::Ec => Ok(SigningAlgorithm::Ec),
        _ => Err(km_err!(
            Unimplemented,
            "only supported algorithms are RSA and EC. Got {}",
            algorithm as u32
        )),
    }
}

/// TIPC service implementation for communication with the HAL service in Android.
struct KMService {
    km_ta: Rc<RefCell<KeyMintTa>>,
}

impl KMService {
    /// Create a service implementation.
    fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
        KMService { km_ta }
    }

    /// Process an incoming request message, returning the response as a collection of fragments
    /// that are each small enough to send over the channel.
    fn handle_message(&self, req_data: &[u8]) -> Result<Vec<Vec<u8>>, Error> {
        let resp = self.km_ta.borrow_mut().process(req_data);
        split_rsp(resp.as_slice(), KEYMINT_MAX_MESSAGE_CONTENT_SIZE)
    }
}

impl Service for KMService {
    type Connection = Context;
    type Message = KMMessage;

    fn on_connect(
        &self,
        _port: &PortCfg,
        _handle: &Handle,
        peer: &Uuid,
    ) -> tipc::Result<ConnectResult<Self::Connection>> {
        debug!("Accepted connection from uuid {:?}.", peer);
        Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
    }

    fn on_message(
        &self,
        _connection: &Self::Connection,
        handle: &Handle,
        msg: Self::Message,
    ) -> tipc::Result<MessageResult> {
        debug!("Received a message.");
        let resp_vec = self.handle_message(&msg.0).map_err(|e| match e {
            Error::Hal(_, err_msg) => {
                error!("Error: {} in handling the message.", err_msg);
                TipcError::InvalidData
            }
            Error::Alloc(err_msg) => {
                error!("Error: {} in handling the message.", err_msg);
                TipcError::AllocError
            }
            _ => TipcError::UnknownError,
        })?;
        for resp in resp_vec {
            handle.send(&KMMessage(resp))?;
        }
        Ok(MessageResult::MaintainConnection)
    }
}

/// Retrieve the system state flag controlling provisioning.
fn get_system_state_provisioning_flag() -> Result<ProvisioningAllowedFlagValues, Error> {
    let system_state_session = SystemState::try_connect().map_err(|e| {
        km_err!(SecureHwCommunicationFailed, "couldn't connect to system state provider: {:?}", e)
    })?;
    let flag =
        system_state_session.get_flag(SystemStateFlag::ProvisioningAllowed).map_err(|e| {
            km_err!(
                SecureHwCommunicationFailed,
                "couldn't get ProvisioningAllowed system state flag: {:?}",
                e
            )
        })?;
    ProvisioningAllowedFlagValues::try_from(flag).map_err(|e| {
        km_err!(
            SecureHwCommunicationFailed,
            "couldn't parse ProvisioningAllowed system state flag from value {}: {:?}",
            flag,
            e
        )
    })
}

/// Indicate whether provisioning is allowed.
fn provisioning_allowed() -> Result<bool, Error> {
    Ok(matches!(
        get_system_state_provisioning_flag()?,
        ProvisioningAllowedFlagValues::ProvisioningAllowed
    ))
}

/// Indicate whether provisioning is allowed during boot.
fn provisioning_allowed_at_boot() -> Result<bool, Error> {
    Ok(matches!(
        get_system_state_provisioning_flag()?,
        ProvisioningAllowedFlagValues::ProvisioningAllowed
            | ProvisioningAllowedFlagValues::ProvisioningAllowedAtBoot
    ))
}

/// TIPC service implementation for communication with components outside Trusty (notably the
/// bootloader and provisioning tools), using legacy (C++) message formats.
struct KMLegacyService {
    km_ta: Rc<RefCell<KeyMintTa>>,
    boot_info: RefCell<Option<BootInfo>>,
    boot_patchlevel: RefCell<Option<u32>>,
}

impl KMLegacyService {
    /// Create a service implementation.
    fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
        KMLegacyService {
            km_ta,
            boot_info: RefCell::new(None),
            boot_patchlevel: RefCell::new(None),
        }
    }

    /// Indicate whether the boot process is complete.
    fn boot_done(&self) -> bool {
        self.km_ta.borrow().is_hal_info_set()
    }

    /// Indicate whether provisioning operations are allowed.
    fn can_provision(&self) -> Result<bool, Error> {
        if self.boot_done() {
            provisioning_allowed()
        } else {
            provisioning_allowed_at_boot()
        }
    }

    /// Set the boot information for the TA if possible (i.e. if all parts of the required
    /// information are available).
    fn maybe_set_boot_info(&self) {
        match (self.boot_info.borrow().as_ref(), self.boot_patchlevel.borrow().as_ref()) {
            (Some(info), Some(boot_patchlevel)) => {
                // All the information is available to set the boot info, so combine it and pass to
                // the TA.
                let boot_info = BootInfo {
                    verified_boot_key: info.verified_boot_key.clone(),
                    device_boot_locked: info.device_boot_locked,
                    verified_boot_state: info.verified_boot_state,
                    verified_boot_hash: info.verified_boot_hash.clone(),
                    boot_patchlevel: *boot_patchlevel,
                };
                if let Err(e) = self.km_ta.borrow_mut().set_boot_info(boot_info) {
                    error!("failed to set boot info: {:?}", e);
                }
            }
            _ => info!("not all boot information available yet"),
        }
    }

    /// Process an incoming request message, returning the corresponding response.
    fn handle_message(&self, req_msg: TrustyPerformOpReq) -> Result<TrustyPerformOpRsp, Error> {
        let cmd_code = req_msg.code();
        // Checking that if we received a bootloader message we are at a stage when we can process
        // it
        if self.boot_done() && legacy::is_trusty_bootloader_req(&req_msg) {
            return Err(km_err!(
                Unimplemented,
                "bootloader command {:?} not allowed after configure command",
                cmd_code
            ));
        }

        if legacy::is_trusty_provisioning_req(&req_msg) && !(self.can_provision()?) {
            return Err(km_err!(Unimplemented, "provisioning command {:?} not allowed", cmd_code));
        }

        // Handling received message
        match req_msg {
            TrustyPerformOpReq::GetVersion(_req) => {
                // Match the values returned by C++ KeyMint (from `AndroidKeymaster::GetVersion`).
                Ok(TrustyPerformOpRsp::GetVersion(GetVersionResponse {
                    major_ver: 2,
                    minor_ver: 0,
                    subminor_ver: 0,
                }))
            }
            TrustyPerformOpReq::GetVersion2(req) => {
                // Match the values returned by C++ KeyMint (from `AndroidKeymaster::GetVersion2`).
                let km_version = legacy::KmVersion::KeyMint3;
                let message_version = km_version.message_version();
                let max_message_version = core::cmp::min(req.max_message_version, message_version);
                Ok(TrustyPerformOpRsp::GetVersion2(GetVersion2Response {
                    max_message_version,
                    km_version,
                    km_date: legacy::KM_DATE,
                }))
            }
            TrustyPerformOpReq::SetBootParams(req) => {
                // Check if this is the first time we receive a SetBootParams cmd
                if self.boot_info.borrow().is_some() {
                    return Err(km_err!(Unimplemented, "command SetBootParams only allowed once"));
                }

                // Saving boot_info so command won't be accepted a second time
                let boot_info = BootInfo {
                    verified_boot_key: req.verified_boot_key,
                    device_boot_locked: req.device_locked,
                    verified_boot_state: req.verified_boot_state,
                    verified_boot_hash: req.verified_boot_hash,
                    boot_patchlevel: 0, // boot_patchlevel is received on ConfigureBootPatchlevel
                };
                self.boot_info.borrow_mut().replace(boot_info);

                // Checking if we can send set boot info with the info we currently have
                self.maybe_set_boot_info();

                Ok(TrustyPerformOpRsp::SetBootParams(SetBootParamsResponse {}))
            }
            TrustyPerformOpReq::ConfigureBootPatchlevel(req) => {
                // Check if this is the first time we receive a ConfigureBootPatchlevel cmd
                if self.boot_patchlevel.borrow().is_some() {
                    return Err(km_err!(
                        Unimplemented,
                        "command ConfigureBootPatchlevel only allowed once"
                    ));
                }

                // Saving boot_patchlevel so command won't be accepted a second time
                self.boot_patchlevel.borrow_mut().replace(req.boot_patchlevel);

                // Checking if we can send set boot info with the info we currently have
                self.maybe_set_boot_info();

                Ok(TrustyPerformOpRsp::ConfigureBootPatchlevel(ConfigureBootPatchlevelResponse {}))
            }
            TrustyPerformOpReq::SetAttestationKey(req) => {
                let algorithm = keymaster_algorithm_to_signing_algorithm(req.algorithm)?;
                secure_storage_manager::provision_attestation_key_file(algorithm, &req.key_data)?;
                Ok(TrustyPerformOpRsp::SetAttestationKey(SetAttestationKeyResponse {}))
            }
            TrustyPerformOpReq::AppendAttestationCertChain(req) => {
                let algorithm = keymaster_algorithm_to_signing_algorithm(req.algorithm)?;
                secure_storage_manager::append_attestation_cert_chain(algorithm, &req.cert_data)?;
                Ok(TrustyPerformOpRsp::AppendAttestationCertChain(
                    AppendAttestationCertChainResponse {},
                ))
            }
            TrustyPerformOpReq::ClearAttestationCertChain(req) => {
                let algorithm = keymaster_algorithm_to_signing_algorithm(req.algorithm)?;
                secure_storage_manager::clear_attestation_cert_chain(algorithm)?;
                Ok(TrustyPerformOpRsp::ClearAttestationCertChain(
                    ClearAttestationCertChainResponse {},
                ))
            }
            TrustyPerformOpReq::SetWrappedAttestationKey(req) => {
                let algorithm = keymaster_algorithm_to_signing_algorithm(req.algorithm)?;
                secure_storage_manager::set_wrapped_attestation_key(algorithm, &req.key_data)?;
                Ok(TrustyPerformOpRsp::SetWrappedAttestationKey(
                    SetWrappedAttestationKeyResponse {},
                ))
            }
            TrustyPerformOpReq::SetAttestationIds(req) => {
                secure_storage_manager::provision_attestation_id_file(
                    &req.brand,
                    &req.product,
                    &req.device,
                    &req.serial,
                    &req.imei,
                    &req.meid,
                    &req.manufacturer,
                    &req.model,
                    None,
                )?;
                Ok(TrustyPerformOpRsp::SetAttestationIds(SetAttestationIdsResponse {}))
            }
            TrustyPerformOpReq::SetAttestationIdsKM3(req) => {
                secure_storage_manager::provision_attestation_id_file(
                    &req.base.brand,
                    &req.base.product,
                    &req.base.device,
                    &req.base.serial,
                    &req.base.imei,
                    &req.base.meid,
                    &req.base.manufacturer,
                    &req.base.model,
                    Some(&req.second_imei),
                )?;
                Ok(TrustyPerformOpRsp::SetAttestationIdsKM3(SetAttestationIdsKM3Response {}))
            }
            TrustyPerformOpReq::AppendUdsCertificate(req) => {
                secure_storage_manager::append_uds_cert_chain(&req.cert_data)?;
                Ok(TrustyPerformOpRsp::AppendUdsCertificate(AppendUdsCertificateResponse {}))
            }
            TrustyPerformOpReq::ClearUdsCertificate(..) => {
                secure_storage_manager::clear_uds_cert_chain()?;
                Ok(TrustyPerformOpRsp::ClearUdsCertificate(ClearUdsCertificateResponse {}))
            }
        }
    }
}

impl Service for KMLegacyService {
    type Connection = Context;
    type Message = KMMessage;

    fn on_connect(
        &self,
        _port: &PortCfg,
        _handle: &Handle,
        peer: &Uuid,
    ) -> tipc::Result<ConnectResult<Self::Connection>> {
        debug!("Accepted connection from uuid {:?}.", peer);
        Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
    }

    fn on_message(
        &self,
        _connection: &Self::Connection,
        handle: &Handle,
        msg: Self::Message,
    ) -> tipc::Result<MessageResult> {
        debug!("Received legacy message.");
        let req_msg = legacy::deserialize_trusty_req(&msg.0).map_err(|e| {
            error!("Received error when parsing legacy message: {:?}", e);
            TipcError::InvalidData
        })?;
        let op = req_msg.code();

        let resp = match self.handle_message(req_msg) {
            Ok(resp_msg) => legacy::serialize_trusty_rsp(resp_msg).map_err(|e| {
                error!("failed to serialize legacy response message: {:?}", e);
                TipcError::InvalidData
            })?,
            Err(Error::Hal(rc, msg)) => {
                error!("operation {:?} failed: {:?} {}", op, rc, msg);
                legacy::serialize_trusty_error_rsp(op, rc).map_err(|e| {
                    error!("failed to serialize legacy error {:?} response message: {:?}", rc, e);
                    TipcError::InvalidData
                })?
            }
            Err(e) => {
                error!("error handling legacy message: {:?}", e);
                return Err(TipcError::UnknownError);
            }
        };
        handle.send(&KMMessage(resp))?;
        Ok(MessageResult::MaintainConnection)
    }
}

/// TIPC service implementation for secure communication with other components in Trusty
/// (e.g. Gatekeeper, ConfirmationUI), using legacy (C++) message formats.
struct KMSecureService {
    km_ta: Rc<RefCell<KeyMintTa>>,
}

impl KMSecureService {
    /// Create a service implementation.
    fn new(km_ta: Rc<RefCell<KeyMintTa>>) -> Self {
        KMSecureService { km_ta }
    }
    fn handle_message(
        &self,
        req_msg: TrustyPerformSecureOpReq,
    ) -> Result<TrustyPerformSecureOpRsp, Error> {
        match req_msg {
            TrustyPerformSecureOpReq::GetAuthTokenKey(_) => {
                match self.km_ta.borrow().get_hmac_key() {
                    Some(mut payload) => {
                        Ok(TrustyPerformSecureOpRsp::GetAuthTokenKey(GetAuthTokenKeyResponse {
                            key_material: mem::take(&mut payload.0),
                        }))
                    }
                    None => Err(km_err!(UnknownError, "hmac_key is not available")),
                }
            }
            TrustyPerformSecureOpReq::GetDeviceInfo(_) => {
                Ok(TrustyPerformSecureOpRsp::GetDeviceInfo(GetDeviceInfoResponse {
                    device_ids: self.km_ta.borrow().rpc_device_info()?,
                }))
            }
            TrustyPerformSecureOpReq::SetAttestationIds(req) => {
                secure_storage_manager::provision_attestation_id_file(
                    &req.brand,
                    &req.product,
                    &req.device,
                    &req.serial,
                    &req.imei,
                    &req.meid,
                    &req.manufacturer,
                    &req.model,
                    None,
                )?;
                Ok(TrustyPerformSecureOpRsp::SetAttestationIds(SetAttestationIdsResponse {}))
            }
        }
    }
}

impl Service for KMSecureService {
    type Connection = Context;
    type Message = KMMessage;

    fn on_connect(
        &self,
        _port: &PortCfg,
        _handle: &Handle,
        peer: &Uuid,
    ) -> tipc::Result<ConnectResult<Self::Connection>> {
        if !keymint_check_target_access_policy(peer) {
            error!("access policy rejected the uuid: {:?}", peer);
            return Ok(ConnectResult::CloseConnection);
        }
        debug!("Accepted connection from uuid {:?}.", peer);
        Ok(ConnectResult::Accept(Context { uuid: peer.clone() }))
    }

    fn on_message(
        &self,
        connection: &Self::Connection,
        handle: &Handle,
        msg: Self::Message,
    ) -> tipc::Result<MessageResult> {
        debug!("Received secure message.");

        let req_msg = legacy::deserialize_trusty_secure_req(&msg.0).map_err(|e| {
            error!("Received error when parsing message: {:?}", e);
            TipcError::InvalidData
        })?;
        let op = req_msg.code();
        if matches!(&req_msg, TrustyPerformSecureOpReq::SetAttestationIds(_))
            && !keymint_check_secure_target_access_policy_provisioning(&connection.uuid)
        {
            error!("access policy rejected the uuid: {:?}", &connection.uuid);
            return Ok(MessageResult::CloseConnection);
        }

        let resp = match self.handle_message(req_msg) {
            Ok(resp_msg) => legacy::serialize_trusty_secure_rsp(resp_msg).map_err(|e| {
                error!("failed to serialize legacy response secure message: {:?}", e);
                TipcError::InvalidData
            })?,
            Err(Error::Hal(rc, msg)) => {
                error!("operation {:?} failed: {:?} {}", op, rc, msg);
                legacy::serialize_trusty_secure_error_rsp(op, rc).map_err(|e| {
                    error!(
                        "failed to serialize legacy error {:?} response secure message: {:?}",
                        rc, e
                    );
                    TipcError::InvalidData
                })?
            }
            Err(e) => {
                error!("error handling secure legacy message: {:?}", e);
                return Err(TipcError::UnknownError);
            }
        };
        handle.send(&KMMessage(resp))?;
        Ok(MessageResult::MaintainConnection)
    }
}

service_dispatcher! {
    enum KMServiceDispatcher {
        KMService,
        KMSecureService,
        KMLegacyService,
    }
}

/// Main loop handler for the KeyMint TA.
pub fn handle_port_connections(
    hw_info: HardwareInfo,
    rpc_info: RpcInfo,
    imp: crypto::Implementation,
    dev: kmr_ta::device::Implementation,
) -> Result<(), Error> {
    let km_ta = Rc::new(RefCell::new(KeyMintTa::new(hw_info, rpc_info, imp, dev)));
    let ns_service = KMService::new(Rc::clone(&km_ta));
    let legacy_service = KMLegacyService::new(Rc::clone(&km_ta));
    let sec_service = KMSecureService::new(km_ta);

    let mut dispatcher = KMServiceDispatcher::<3>::new()
        .map_err(|e| km_err!(UnknownError, "could not create multi-service dispatcher: {:?}", e))?;
    let cfg = PortCfg::new(KM_NS_TIPC_SRV_PORT)
        .map_err(|e| {
            km_err!(
                UnknownError,
                "could not create port config for {}: {:?}",
                KM_NS_TIPC_SRV_PORT,
                e
            )
        })?
        .allow_ta_connect()
        .allow_ns_connect();
    dispatcher.add_service(Rc::new(ns_service), cfg).map_err(|e| {
        km_err!(UnknownError, "could not add non-secure service to dispatcher: {:?}", e)
    })?;
    let cfg = PortCfg::new(KM_SEC_TIPC_SRV_PORT)
        .map_err(|e| {
            km_err!(
                UnknownError,
                "could not create port config for {}: {:?}",
                KM_SEC_TIPC_SRV_PORT,
                e
            )
        })?
        .allow_ta_connect();
    dispatcher.add_service(Rc::new(sec_service), cfg).map_err(|e| {
        km_err!(UnknownError, "could not add secure service to dispatcher: {:?}", e)
    })?;
    let cfg = PortCfg::new(KM_NS_LEGACY_TIPC_SRV_PORT)
        .map_err(|e| {
            km_err!(
                UnknownError,
                "could not create port config for {}: {:?}",
                KM_NS_LEGACY_TIPC_SRV_PORT,
                e
            )
        })?
        .allow_ta_connect()
        .allow_ns_connect();
    dispatcher.add_service(Rc::new(legacy_service), cfg).map_err(|e| {
        km_err!(UnknownError, "could not add secure service to dispatcher: {:?}", e)
    })?;
    let buffer = [0u8; 4096];
    let manager =
        Manager::<_, _, PORT_COUNT, MAX_CONNECTION_COUNT>::new_with_dispatcher(dispatcher, buffer)
            .map_err(|e| km_err!(UnknownError, "could not create service manager: {:?}", e))?;
    manager
        .run_event_loop()
        .map_err(|e| km_err!(UnknownError, "service manager received error: {:?}", e))?;
    Err(km_err!(SecureHwCommunicationFailed, "KeyMint TA handler terminated unexpectedly."))
}

// TODO: remove when tests reinstated
#[allow(dead_code)]
#[cfg(test)]
mod tests {
    use super::*;
    use kmr_wire::{
        keymint::{ErrorCode, VerifiedBootState},
        legacy::{self, InnerSerialize},
    };
    use test::{expect, skip};
    use trusty_std::ffi::{CString, FallibleCString};

    const CONFIGURE_BOOT_PATCHLEVEL_CMD: u32 =
        legacy::TrustyKeymasterOperation::ConfigureBootPatchlevel as u32;
    const SET_BOOT_PARAMS_CMD: u32 = legacy::TrustyKeymasterOperation::SetBootParams as u32;
    const SET_ATTESTATION_IDS_CMD: u32 = legacy::TrustyKeymasterOperation::SetAttestationIds as u32;
    const SET_ATTESTATION_KEY_CMD: u32 = legacy::TrustyKeymasterOperation::SetAttestationKey as u32;

    #[test]
    fn connection_test() {
        if !cfg!(kmr_enabled) {
            skip!("KeyMint Rust TA not configured");
        }

        // Only doing a connection test because the auth token key is not available for unittests.
        let port1 = CString::try_new(KM_NS_TIPC_SRV_PORT).unwrap();
        let _session1 = Handle::connect(port1.as_c_str()).unwrap();
        let port2 = CString::try_new(KM_SEC_TIPC_SRV_PORT).unwrap();
        let _session2 = Handle::connect(port2.as_c_str()).unwrap();
        let port3 = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
        let _session3 = Handle::connect(port3.as_c_str()).unwrap();
    }

    #[test]
    fn test_access_policy() {
        if !cfg!(kmr_enabled) {
            skip!("KeyMint Rust TA not configured");
        }

        // Test whether the access policy is in action.
        // Keymint unit test app should be able to connect to the KM secure service.
        let port = CString::try_new(KM_SEC_TIPC_SRV_PORT).unwrap();
        Handle::connect(port.as_c_str())
            .expect("Keymint unit test app should be able to connect to the KM secure service");

        // Keymint unit test app should not be able to call the attestation id provisioning API
        // in the KM secure service.
        let err = set_attestation_ids_secure().expect_err(
            "An error is expected. Keymint unit test app shouldn't be able to provision",
        );
        assert_eq!(err, TipcError::SystemError(trusty_sys::Error::NoMsg));
    }

    fn check_response_status(rsp: &KMMessage) -> Result<(), ErrorCode> {
        let error_code = legacy::deserialize_trusty_rsp_error_code(&rsp.0)
            .expect("Couldn't retrieve error code");
        if error_code == ErrorCode::Ok {
            Ok(())
        } else {
            Err(error_code)
        }
    }

    fn get_message_request(cmd: u32) -> Vec<u8> {
        (cmd << legacy::TRUSTY_CMD_SHIFT).to_ne_bytes().to_vec()
    }

    fn get_response_status(session: &Handle) -> Result<(), ErrorCode> {
        let mut buf = [0; KEYMINT_MAX_BUFFER_LENGTH as usize];
        let response: KMMessage =
            session.recv(&mut buf).map_err(|_| ErrorCode::SecureHwCommunicationFailed)?;
        check_response_status(&response)
    }

    fn get_configure_boot_patchlevel_message(
        boot_patchlevel: u32,
    ) -> Result<Vec<u8>, legacy::Error> {
        let mut req = get_message_request(CONFIGURE_BOOT_PATCHLEVEL_CMD);
        boot_patchlevel.serialize_into(&mut req)?;
        Ok(req)
    }

    fn get_set_boot_params_message(
        os_version: u32,
        os_patchlevel: u32,
        device_locked: bool,
        verified_boot_state: VerifiedBootState,
        verified_boot_key: Vec<u8>,
        verified_boot_hash: Vec<u8>,
    ) -> Result<Vec<u8>, legacy::Error> {
        let mut req = get_message_request(SET_BOOT_PARAMS_CMD);
        os_version.serialize_into(&mut req)?;
        os_patchlevel.serialize_into(&mut req)?;
        device_locked.serialize_into(&mut req)?;
        verified_boot_state.serialize_into(&mut req)?;
        verified_boot_key.serialize_into(&mut req)?;
        verified_boot_hash.serialize_into(&mut req)?;
        Ok(req)
    }

    fn get_set_attestation_ids_message(
        brand: &Vec<u8>,
        product: &Vec<u8>,
        device: &Vec<u8>,
        serial: &Vec<u8>,
        imei: &Vec<u8>,
        meid: &Vec<u8>,
        manufacturer: &Vec<u8>,
        model: &Vec<u8>,
    ) -> Result<Vec<u8>, legacy::Error> {
        let mut req = get_message_request(SET_ATTESTATION_IDS_CMD);
        brand.serialize_into(&mut req)?;
        product.serialize_into(&mut req)?;
        device.serialize_into(&mut req)?;
        serial.serialize_into(&mut req)?;
        imei.serialize_into(&mut req)?;
        meid.serialize_into(&mut req)?;
        manufacturer.serialize_into(&mut req)?;
        model.serialize_into(&mut req)?;
        Ok(req)
    }

    fn get_set_attestation_key_message(
        algorithm: Algorithm,
        content: &[u8],
    ) -> Result<Vec<u8>, legacy::Error> {
        let mut req = get_message_request(SET_ATTESTATION_KEY_CMD);
        (algorithm as u32).serialize_into(&mut req)?;
        (content.len() as u32).serialize_into(&mut req)?;
        req.extend_from_slice(content);
        Ok(req)
    }

    // This test should only be run manually as it writes to the secure storage
    // of the device under test.
    // #[test]
    fn set_attestation_keys_certs() {
        let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
        let session = Handle::connect(port.as_c_str()).unwrap();

        let req = get_set_attestation_key_message(Algorithm::Ec, &[0; 1024])
            .expect("couldn't construct SetAttestatonKey request");
        let set_attestation_key_req = KMMessage(req);
        // Sending `SetAttestationKey` request and processing response
        session.send(&set_attestation_key_req).unwrap();
        let buf = &mut [0; KEYMINT_MAX_BUFFER_LENGTH as usize];
        let response: KMMessage = session.recv(buf).expect("Didn't get response");
        let km_error_code = check_response_status(&response);
        expect!(km_error_code.is_ok(), "Should be able to call SetAttestatonKeys");
    }

    fn set_attestation_ids_secure() -> tipc::Result<()> {
        let port = CString::try_new(KM_SEC_TIPC_SRV_PORT).unwrap();
        let session = Handle::connect(port.as_c_str()).unwrap();

        // Creating a SetAttestationIds message
        let brand = b"no brand".to_vec();
        let device = b"a new device".to_vec();
        let product = b"p1".to_vec();
        let serial = vec![b'5'; 64];
        let imei = b"7654321".to_vec();
        let meid = b"1234567".to_vec();
        let manufacturer = b"a manufacturer".to_vec();
        let model = b"the new one".to_vec();
        let req = get_set_attestation_ids_message(
            &brand,
            &device,
            &product,
            &serial,
            &imei,
            &meid,
            &manufacturer,
            &model,
        )
        .expect("couldn't construct SetAttestatonIds request");
        let set_attestation_ids_req = KMMessage(req);

        // Sending SetAttestationIds
        session.send(&set_attestation_ids_req).unwrap();
        let buf = &mut [0; KEYMINT_MAX_BUFFER_LENGTH as usize];
        session.recv(buf)
    }

    // This test should only be run manually as it writes to the secure storage
    // of the device under test.
    // #[test]
    fn set_attestation_ids() {
        if !cfg!(kmr_enabled) {
            skip!("KeyMint Rust TA not configured");
        }

        let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
        let session = Handle::connect(port.as_c_str()).unwrap();

        // Creating a SetAttestationIds message
        let brand = b"no brand".to_vec();
        let device = b"a new device".to_vec();
        let product = b"p1".to_vec();
        let serial = vec![b'5'; 64];
        let imei = b"7654321".to_vec();
        let meid = b"1234567".to_vec();
        let manufacturer = b"a manufacturer".to_vec();
        let model = b"the new one".to_vec();
        let req = get_set_attestation_ids_message(
            &brand,
            &device,
            &product,
            &serial,
            &imei,
            &meid,
            &manufacturer,
            &model,
        )
        .expect("couldn't construct SetAttestatonIds request");
        let set_attestation_ids_req = KMMessage(req);

        // Sending SetAttestationIds
        session.send(&set_attestation_ids_req).unwrap();
        let buf = &mut [0; KEYMINT_MAX_BUFFER_LENGTH as usize];
        let response: KMMessage = session.recv(buf).expect("Didn't get response");
        let km_error_code = check_response_status(&response);
        expect!(km_error_code.is_ok(), "Should be able to call SetAttestationIds");
    }

    // The following tests are all skipped because they try to SetBootParams more than once
    // which isn't allowed.  However, the code is preserved to allow for future manual testing.

    #[test]
    fn send_setbootparams_configure_setbootparams_configure() {
        if true {
            skip!("SetBootParams cannot be performed more than once");
        }

        let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
        let session = Handle::connect(port.as_c_str()).unwrap();

        // Creating a SetBootParams message
        let os_version = 1;
        let os_patchlevel = 0x202010;
        let device_locked = true;
        let verified_boot_state = VerifiedBootState::Unverified;
        let verified_boot_key = [0u8; 32];
        let verified_boot_hash = [0u8; 32];
        let req = get_set_boot_params_message(
            os_version,
            os_patchlevel,
            device_locked,
            verified_boot_state,
            verified_boot_key.to_vec(),
            verified_boot_hash.to_vec(),
        )
        .expect("couldn't construct SetBootParams request");
        let set_boot_param_req = KMMessage(req);

        // Sending SetBootParamsRequest
        session.send(&set_boot_param_req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");

        // Creating a ConfigureBootPatchlevelRequest message
        let boot_patchlevel = 0x20201010;
        let req =
            get_configure_boot_patchlevel_message(boot_patchlevel).expect("Couldn't construct msg");
        let configure_bootpatchlevel_req = KMMessage(req);

        // Sending ConfigureBootPatchlevelRequest
        session.send(&configure_bootpatchlevel_req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");

        // Checking that sending the message a second time fails
        session.send(&set_boot_param_req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_err(), "Shouldn't be able to call SetBootParams a second time");

        // Checking that sending the message a second time fails
        session.send(&configure_bootpatchlevel_req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(
            km_error_code.is_err(),
            "Shouldn't be able to call ConfigureBootPatchlevel a second time"
        );
    }

    #[test]
    fn send_configure_configure_setbootparams_setbootparams() {
        if true {
            skip!("SetBootParams cannot be performed more than once");
        }

        let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
        let session = Handle::connect(port.as_c_str()).unwrap();

        // Creating a ConfigureBootPatchlevelRequest message
        let boot_patchlevel = 0x20201010;
        let req =
            get_configure_boot_patchlevel_message(boot_patchlevel).expect("Couldn't construct msg");
        let req = KMMessage(req);

        // Sending ConfigureBootPatchlevelRequest
        session.send(&req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");

        // Checking that sending the message a second time fails
        session.send(&req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(
            km_error_code.is_err(),
            "Shouldn't be able to call ConfigureBootPatchlevel a second time"
        );

        // Creating a SetBootParams message
        let os_version = 1;
        let os_patchlevel = 0x202010;
        let device_locked = true;
        let verified_boot_state = VerifiedBootState::Unverified;
        let verified_boot_key = [0u8; 32];
        let verified_boot_hash = [0u8; 32];
        let req = get_set_boot_params_message(
            os_version,
            os_patchlevel,
            device_locked,
            verified_boot_state,
            verified_boot_key.to_vec(),
            verified_boot_hash.to_vec(),
        )
        .expect("couldn't construct SetBootParams request");
        let req = KMMessage(req);

        // Sending SetBootParamsRequest
        session.send(&req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");

        // Checking that sending the message a second time fails
        session.send(&req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_err(), "Shouldn't be able to call SetBootParams a second time");
    }

    #[test]
    fn send_setbootparams_setbootparams_configure_configure() {
        if true {
            skip!("SetBootParams cannot be performed more than once");
        }

        let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
        let session = Handle::connect(port.as_c_str()).unwrap();

        // Creating a SetBootParams message
        let os_version = 1;
        let os_patchlevel = 0x202010;
        let device_locked = true;
        let verified_boot_state = VerifiedBootState::Unverified;
        let verified_boot_key = [0u8; 32];
        let verified_boot_hash = [0u8; 32];
        let req = get_set_boot_params_message(
            os_version,
            os_patchlevel,
            device_locked,
            verified_boot_state,
            verified_boot_key.to_vec(),
            verified_boot_hash.to_vec(),
        )
        .expect("couldn't construct SetBootParams request");
        let req = KMMessage(req);

        // Sending SetBootParamsRequest
        session.send(&req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");

        // Checking that sending the message a second time fails
        session.send(&req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_err(), "Shouldn't be able to call SetBootParams a second time");

        // Creating a ConfigureBootPatchlevelRequest message
        let boot_patchlevel = 0x20201010;
        let req =
            get_configure_boot_patchlevel_message(boot_patchlevel).expect("Couldn't construct msg");
        let req = KMMessage(req);

        // Sending ConfigureBootPatchlevelRequest
        session.send(&req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");

        // Checking that sending the message a second time fails
        session.send(&req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(
            km_error_code.is_err(),
            "Shouldn't be able to call ConfigureBootPatchlevel a second time"
        );
    }

    #[test]
    fn send_configure_setbootparams_setbootparams_configure() {
        if true {
            skip!("SetBootParams cannot be performed more than once");
        }

        let port = CString::try_new(KM_NS_LEGACY_TIPC_SRV_PORT).unwrap();
        let session = Handle::connect(port.as_c_str()).unwrap();

        // Creating a ConfigureBootPatchlevelRequest message
        let boot_patchlevel = 0x20201010;
        let req =
            get_configure_boot_patchlevel_message(boot_patchlevel).expect("Couldn't construct msg");
        let configure_bootpatchlevel_req = KMMessage(req);

        // Sending ConfigureBootPatchlevelRequest
        session.send(&configure_bootpatchlevel_req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_ok(), "Should be able to call ConfigureBootPatchlevel");

        // Creating a SetBootParams message
        let os_version = 1;
        let os_patchlevel = 0x202010;
        let device_locked = true;
        let verified_boot_state = VerifiedBootState::Unverified;
        let verified_boot_key = [0u8; 32];
        let verified_boot_hash = [0u8; 32];
        let req = get_set_boot_params_message(
            os_version,
            os_patchlevel,
            device_locked,
            verified_boot_state,
            verified_boot_key.to_vec(),
            verified_boot_hash.to_vec(),
        )
        .expect("couldn't construct SetBootParams request");
        let set_boot_param_req = KMMessage(req);

        // Sending SetBootParamsRequest
        session.send(&set_boot_param_req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_ok(), "Should be able to call SetBootParams");

        // Checking that sending the message a second time fails
        session.send(&set_boot_param_req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(km_error_code.is_err(), "Shouldn't be able to call SetBootParams a second time");

        // Checking that sending the message a second time fails
        session.send(&configure_bootpatchlevel_req).unwrap();
        let km_error_code = get_response_status(&session);
        expect!(
            km_error_code.is_err(),
            "Shouldn't be able to call ConfigureBootPatchlevel a second time"
        );
    }
}
