/*
 * 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 implementation of StorageKeyWrapper trait.
use alloc::vec::Vec;
use core::ffi::CStr;
use kmr_common::{
    crypto,
    crypto::{aes, Aes, KeyMaterial, OpaqueKeyMaterial, OpaqueOr},
    get_bool_tag_value, get_opt_tag_value, get_tag_value, km_err, vec_try, vec_try_with_capacity,
    Error,
};
use kmr_crypto_boring::aes::BoringAes;
use kmr_ta::device::StorageKeyWrapper;
use kmr_wire::{keymint, keymint::ErrorCode, KeySizeInBits};
use log::warn;
use tipc::Handle;

/// TIPC port used for communication with the `hwwsk` service.
const HWWSK_PORT: &[u8] = b"com.android.trusty.hwwsk\0";

/// Create a session for `hwwsk` communication.
fn hwwsk_session() -> Result<Handle, Error> {
    let port = CStr::from_bytes_with_nul(HWWSK_PORT).expect("HWWSK_PORT was not null terminated");
    Handle::connect(port)
        .map_err(|e| km_err!(SecureHwCommunicationFailed, "failed to connect to hwwsk: {:?}", e))
}

/// Storage key wrapper implementation for Trusty.
pub struct TrustyStorageKeyWrapper;

impl StorageKeyWrapper for TrustyStorageKeyWrapper {
    fn ephemeral_wrap(&self, key_material: &KeyMaterial) -> Result<Vec<u8>, Error> {
        let wrapped_key = match key_material {
            KeyMaterial::Aes(OpaqueOr::Opaque(key)) => key,
            _ => {
                return Err(km_err!(
                    UnsupportedAlgorithm,
                    "only opaque AES storage keys are supported"
                ))
            }
        };
        let key = &wrapped_key.0;
        let session = hwwsk_session()?;
        let buf = &mut [0u8; hwwsk::HWWSK_MAX_MSG_SIZE as usize];
        let wrapped_key_buffer = hwwsk::export_key(&session, buf, key).map_err(|e| {
            km_err!(SecureHwCommunicationFailed, "hwwsk failed to wrap key: {:?}", e)
        })?;
        let mut wrapped_key = vec_try_with_capacity!(wrapped_key_buffer.len())?;
        wrapped_key.extend_from_slice(wrapped_key_buffer);
        Ok(wrapped_key)
    }
}

/// Wrapper around `BoringAes` implementation that intercepts storage keys.
pub struct TrustyAes(BoringAes);

impl Default for TrustyAes {
    fn default() -> Self {
        Self(BoringAes)
    }
}
impl TrustyAes {
    fn create_storage_key(
        &self,
        key: Option<aes::Key>,
        params: &[keymint::KeyParam],
    ) -> Result<crypto::KeyMaterial, Error> {
        // Storage keys should not work for normal operations.  The TA code polices this by watching
        // for `Tag::StorageKey`; also police here by rejecting keys that have a `Tag::BlockMode`
        // attached.
        if get_opt_tag_value!(params, BlockMode)?.is_some() {
            return Err(km_err!(UnsupportedTag, "don't expect block mode on storage key"));
        }
        let key_size = get_tag_value!(params, KeySize, ErrorCode::UnsupportedTag)?;
        let key_size = key_size.0 as usize;
        let mut key_flags = hwwsk::KeyFlags::new();
        let rollback_resistance = get_bool_tag_value!(params, RollbackResistance)?;
        if rollback_resistance {
            key_flags = key_flags.rollback_resistance();
        };

        let session = hwwsk_session()?;
        let mut buf = vec_try![0; hwwsk::HWWSK_MAX_MSG_SIZE as usize]?;
        let key_material: Option<&[u8]> = match key.as_ref() {
            None => None,
            Some(aes_key) => Some(match aes_key {
                aes::Key::Aes128(key) => key,
                aes::Key::Aes192(key) => key,
                aes::Key::Aes256(key) => key,
            }),
        };
        let mut result = match key_material {
            None => hwwsk::generate_key(&session, &mut buf, key_size, key_flags),
            Some(key) => hwwsk::import_key(&session, &mut buf, key_size, key_flags, key),
        };
        if result == Err(hwwsk::HwWskError::NotSupported) && rollback_resistance {
            warn!("failed to generate rollback-resistant storage key, retrying without resistance");
            key_flags = hwwsk::KeyFlags::new();
            result = match key_material {
                None => hwwsk::generate_key(&session, &mut buf, key_size, key_flags),
                Some(key) => hwwsk::import_key(&session, &mut buf, key_size, key_flags, key),
            };
        }

        let wrapped_key_buffer =
            result.map_err(|e| km_err!(UnknownError, "hwwsk failed to create key: {:?}", e))?;

        let mut wrapped_key = vec_try_with_capacity!(wrapped_key_buffer.len())?;
        wrapped_key.extend_from_slice(wrapped_key_buffer);
        Ok(crypto::KeyMaterial::Aes(OpaqueOr::Opaque(OpaqueKeyMaterial(wrapped_key))))
    }
}

impl Aes for TrustyAes {
    fn generate_key(
        &self,
        rng: &mut dyn crypto::Rng,
        variant: aes::Variant,
        params: &[keymint::KeyParam],
    ) -> Result<crypto::KeyMaterial, Error> {
        if !get_bool_tag_value!(params, StorageKey)? {
            // For normal (non-storage) keys, pass on to BoringSSL implementation.
            return self.0.generate_key(rng, variant, params);
        }
        self.create_storage_key(None, params)
    }

    fn import_key(
        &self,
        data: &[u8],
        params: &[keymint::KeyParam],
    ) -> Result<(crypto::KeyMaterial, KeySizeInBits), Error> {
        if !get_bool_tag_value!(params, StorageKey)? {
            // For normal (non-storage) keys, pass on to BoringSSL implementation.
            return self.0.import_key(data, params);
        }

        let aes_key = aes::Key::new_from(data)?;
        let key_size = aes_key.size();
        Ok((self.create_storage_key(Some(aes_key), params)?, key_size))
    }

    fn begin(
        &self,
        key: OpaqueOr<aes::Key>,
        mode: aes::CipherMode,
        dir: crypto::SymmetricOperation,
    ) -> Result<Box<dyn crypto::EmittingOperation>, Error> {
        match key {
            OpaqueOr::Explicit(_) => self.0.begin(key, mode, dir),
            OpaqueOr::Opaque(_) => {
                Err(km_err!(StorageKeyUnsupported, "attempt to use storage key"))
            }
        }
    }

    fn begin_aead(
        &self,
        key: OpaqueOr<aes::Key>,
        mode: aes::GcmMode,
        dir: crypto::SymmetricOperation,
    ) -> Result<Box<dyn crypto::AadOperation>, Error> {
        match key {
            OpaqueOr::Explicit(_) => self.0.begin_aead(key, mode, dir),
            OpaqueOr::Opaque(_) => {
                Err(km_err!(StorageKeyUnsupported, "attempt to use storage key"))
            }
        }
    }
}

// Not adding unit tests because we do not have a mock server on AOSP for hwwsk.
