/*
 * 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 kmr_common::{
    crypto, km_err,
    wire::legacy::{
        self, ConfigureBootPatchlevelResponse, GetAuthTokenKeyResponse, GetDeviceInfoResponse,
        GetVersion2Response, GetVersionResponse, SetAttestationIdsKM3Response,
        SetAttestationIdsResponse, SetAttestationKeyResponse, SetBootParamsResponse,
        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, Deserialize, Handle, Manager, PortCfg, Serialize, Serializer, Service,
    TipcError, Uuid,
};
use trusty_std::alloc::FallibleVec;
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";

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>]) -> Result<Self, TipcError> {
        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<'a> {
    km_ta: Rc<RefCell<KeyMintTa<'a>>>,
}

impl<'a> KMService<'a> {
    /// Create a service implementation.
    fn new(km_ta: Rc<RefCell<KeyMintTa<'a>>>) -> 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<'a> Service for KMService<'a> {
    type Connection = Context;
    type Message = KMMessage;

    fn on_connect(
        &self,
        _port: &PortCfg,
        _handle: &Handle,
        peer: &Uuid,
    ) -> Result<Option<Self::Connection>, TipcError> {
        info!("Accepted connection from Uuid {:?}.", peer);
        Ok(Some(Context { _uuid: peer.clone() }))
    }

    fn on_message(
        &self,
        _connection: &Self::Connection,
        handle: &Handle,
        msg: Self::Message,
    ) -> Result<bool, TipcError> {
        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(true)
    }
}

/// 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(match get_system_state_provisioning_flag()? {
        ProvisioningAllowedFlagValues::ProvisioningAllowed => true,
        _ => false,
    })
}

/// Indicate whether provisioning is allowed during boot.
fn provisioning_allowed_at_boot() -> Result<bool, Error> {
    Ok(match get_system_state_provisioning_flag()? {
        ProvisioningAllowedFlagValues::ProvisioningAllowed => true,
        ProvisioningAllowedFlagValues::ProvisioningAllowedAtBoot => true,
        _ => false,
    })
}

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

impl<'a> KMLegacyService<'a> {
    /// Create a service implementation.
    fn new(km_ta: Rc<RefCell<KeyMintTa<'a>>>) -> 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::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 {}))
            }
            // TODO: Check if we need to support other provisioning messages:
            // (AppendAttestationCertChain, ClearAttestationCertChain, SetWrappedAttestationKey)
            _ => Err(km_err!(Unimplemented, "received command {:?} not supported", cmd_code)),
        }
    }
}

impl<'a> Service for KMLegacyService<'a> {
    type Connection = Context;
    type Message = KMMessage;

    fn on_connect(
        &self,
        _port: &PortCfg,
        _handle: &Handle,
        peer: &Uuid,
    ) -> Result<Option<Self::Connection>, TipcError> {
        info!("Accepted connection from Uuid {:?}.", peer);
        Ok(Some(Context { _uuid: peer.clone() }))
    }

    fn on_message(
        &self,
        _connection: &Self::Connection,
        handle: &Handle,
        msg: Self::Message,
    ) -> Result<bool, TipcError> {
        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(true)
    }
}

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

impl<'a> KMSecureService<'a> {
    /// Create a service implementation.
    fn new(km_ta: Rc<RefCell<KeyMintTa<'a>>>) -> 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<'a> Service for KMSecureService<'a> {
    type Connection = Context;
    type Message = KMMessage;

    fn on_connect(
        &self,
        _port: &PortCfg,
        _handle: &Handle,
        peer: &Uuid,
    ) -> Result<Option<Self::Connection>, TipcError> {
        info!("Accepted connection from Uuid {:?}.", peer);
        Ok(Some(Context { _uuid: peer.clone() }))
    }

    fn on_message(
        &self,
        _connection: &Self::Connection,
        handle: &Handle,
        msg: Self::Message,
    ) -> Result<bool, TipcError> {
        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();

        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(true)
    }
}

service_dispatcher! {
    enum KMServiceDispatcher<'a> {
        KMService<'a>,
        KMSecureService<'a>,
        KMLegacyService<'a>,
    }
}

/// Main loop handler for the KeyMint TA.
pub fn handle_port_connections<'a>(
    hw_info: HardwareInfo,
    rpc_info: RpcInfo,
    imp: crypto::Implementation<'a>,
    dev: kmr_ta::device::Implementation<'a>,
) -> 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::<_, _, 3, 4>::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;
    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;

    // TODO: Removing tests for now until we have the Rust implementation as the default keymint;
    //       put them back once we finish switching to the Rust implementation.

    //#[test]
    fn connection_test() {
        // 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();
    }

    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)
    }

    //#[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");
    }

    //#[test]
    fn set_attestation_ids() {
        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");
    }

    //#[test]
    fn send_setbootparams_configure_setbootparams_configure() {
        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"
        );
    }

    // Not running the next 3 tests because we never restart the server, which means that
    // the server remembers the commands from the previous test. Also not using #[ignore] because
    // it doesn't seem to be supported yet.

    //#[test]
    #[allow(dead_code)]
    fn send_configure_configure_setbootparams_setbootparams() {
        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]
    #[allow(dead_code)]
    fn send_setbootparams_setbootparams_configure_configure() {
        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]
    #[allow(dead_code)]
    fn send_configure_setbootparams_setbootparams_configure() {
        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"
        );
    }
}
