/*
 * 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.
 */

//! Module that implements the [`SecureDeletionSecretManager`] trait.
use alloc::rc::Rc;
use core::{
    cell::RefCell,
    cmp,
    ops::{Deref, DerefMut},
};
use kmr_common::{
    crypto,
    keyblob::{SecureDeletionData, SecureDeletionSecretManager, SecureDeletionSlot, SlotPurpose},
    km_err, Error,
};
use log::{debug, error, info};
use storage::{self as storage_session, OpenMode, Port, SecureFile, Session, Transaction};
use trusty_sys;
use zeroize::{Zeroize, ZeroizeOnDrop};

// Maximum number of attempts to perform a secure storage transaction to read or
// delete a secure deletion secret.  Because the storageproxy may be restarted
// while this code is running, it may be necessary to retry.  But because it's
// unclear exactly what error codes may be returned when the proxy is shut down,
// we conservatively retry all unexpected errors.  To avoid an infinite loop, we
// set a limit on the number of retries (though hitting the limit and returning
// an error will likely break the boot anyway).  Ideally, we should never need
// more than one retry.  We allow three.
const KM_MAX_TRIES: usize = 3;

// Each secret is 16 bytes.
const KM_SECRET_SIZE: usize = 16;
// The factory reset secret is composed of two secrets, so 32 bytes, and it is
// stored at offset 0. After this position (offset 32), all the secrets are
// stored one after the other. On each secret a single bit on the first byte is
// set to indicate that the secret is valid (mask 0x80). Any unused secret/newly
// allocated space on the file is set to 0
const KM_FACTORY_RESET_SECRET_SIZE: usize = KM_SECRET_SIZE * 2;
const KM_FACTORY_RESET_SECRET_POS: usize = 0;
const KM_FACTORY_FIRST_SECURE_DELETION_SECRET_POS: usize =
    KM_FACTORY_RESET_SECRET_POS + KM_FACTORY_RESET_SECRET_SIZE;

// We read secrets in blocks of 32, so 512 bytes.
const KM_BLOCK_SIZE: usize = KM_SECRET_SIZE * 32;

// Limit file size to 16 KiB (except for key upgrades, see
// KM_MAX_SECRET_FILE_SIZE_FOR_UPGRADES).
const KM_MAX_SECRET_FILE_SIZE: usize = KM_BLOCK_SIZE * 32;

// This is a higher file size limit, with the space above KM_MAX_SECRET_FILE_SIZE
// usable only for key IDs that need to be written as part of a key upgrade.
// This is to reduce the probability that keys are degraded as a result of
// upgrading.
const KM_MAX_SECRET_FILE_SIZE_FOR_UPGRADES: usize = KM_MAX_SECRET_FILE_SIZE + 8 * KM_BLOCK_SIZE;

// We set a bit in the first byte of each slot to indicate that the slot is in
// use. This reduces the maximum entropy of each slot to 127 bits.
const KM_IN_USE_FLAG: u8 = 0x80;

// Name of the file to store secrets. The "_1" suffix is to allow for new file
// formats/versions in the future.
const KM_SECURE_DELETION_SECRET_FILENAME: &'static str = "SecureDeletionSecrets_1";

const _: () = assert!(
    KM_BLOCK_SIZE >= KM_FACTORY_RESET_SECRET_SIZE,
    "KM_BLOCK_SIZE should be bigger than KM_FACTORY_RESET_SECRET_SIZE"
);
const _: () = assert!((KM_BLOCK_SIZE % KM_SECRET_SIZE) == 0, "Broke find_empty_slot assumption");
const _: () = assert!(
    (KM_FACTORY_RESET_SECRET_SIZE % KM_SECRET_SIZE) == 0,
    "Broke find_empty_slot assumption"
);

struct SecureDeletionSecretFileSession {
    session: Session,
}

struct SecureDeletionSecretFile<'a> {
    file: SecureFile,
    transaction: Transaction<'a>,
}

enum RetrieveSecureDeletionSecretFileData<'a> {
    EmptyFileFound(SecureDeletionSecretFile<'a>),
    CachedDataFound(SecureDeletionData),
    DataFoundOnFile(SecureDeletionData),
}

impl SecureDeletionSecretFileSession {
    fn new(wait_on_port: bool) -> Result<Self, Error> {
        let mut session = Session::new(Port::TamperProof, wait_on_port).map_err(|_| {
            km_err!(
                SecureHwCommunicationFailed,
                "Failed to connect to secure storage port for opening secure deletion secret file"
            )
        })?;
        Ok(SecureDeletionSecretFileSession { session })
    }

    fn delete_file(&mut self) -> Result<(), Error> {
        // We do not consider the file not existing an error when trying to delete it because the
        // end result is the same.
        match self.session.remove(KM_SECURE_DELETION_SECRET_FILENAME) {
            Ok(_) => Ok(()),
            Err(storage_session::Error::Code(trusty_sys::Error::NotFound)) => Ok(()),
            Err(_) => {
                Err(km_err!(SecureHwCommunicationFailed, "Couldn't delete secure secrets file"))
            }
        }
    }

    fn close(self) {
        self.session.close()
    }
}

impl<'a> SecureDeletionSecretFile<'a> {
    fn open_or_create(
        session: &'a mut SecureDeletionSecretFileSession,
    ) -> Result<SecureDeletionSecretFile<'a>, Error> {
        let mut transaction = session.session.begin_transaction();
        let mut file =
            transaction.open_file(KM_SECURE_DELETION_SECRET_FILENAME, OpenMode::Create).map_err(
                |_| km_err!(SecureHwCommunicationFailed, "Failed open secure deletion secret file"),
            )?;
        Ok(SecureDeletionSecretFile { transaction, file })
    }

    fn read_block<'buf>(
        &mut self,
        start: usize,
        buffer: &'buf mut [u8],
    ) -> Result<&'buf [u8], Error> {
        let req_len = buffer.len();
        let data = self.transaction.read_at(&self.file, start, buffer).map_err(|_| {
            km_err!(
                SecureHwCommunicationFailed,
                "Failed to read secure deletion secret file at offset {} with len {}",
                start,
                req_len
            )
        })?;
        if data.len() != req_len {
            Err(km_err!(
                UnknownError,
                "Couldn't read {} bytes of secure deletion secret file at offset {}. Read {} bytes",
                req_len,
                start,
                data.len()
            ))
        } else {
            Ok(data)
        }
    }

    // Find empty slot is used to find the first [KM_SECRET_SIZE] position on the secure file that
    // isn't currently in use. For this it will read the secure file in [KM_BLOCK_SIZE] chunks and
    // move in [KM_SECRET_SIZE] increments; checking if the KM_IN_USE_FLAG if set on that position.
    fn find_empty_slot(&mut self, is_upgrade: bool) -> Result<usize, Error> {
        let end = SecureDeletionSecretFile::get_max_file_size(is_upgrade);
        let file_size = self.get_file_size()?;
        let end = cmp::min(end, file_size);
        let mut key_slot = 0;
        let mut block_buffer = [0; KM_BLOCK_SIZE];
        'search_loop: for start_pos in (0..end).step_by(KM_BLOCK_SIZE) {
            let read_data = match self.read_block(start_pos, &mut block_buffer) {
                Ok(read_data) => read_data,
                Err(e) => {
                    error!("Failed to read block of secrets");
                    return Err(e);
                }
            };
            if read_data.len() != KM_BLOCK_SIZE {
                return Err(km_err!(
                    SecureHwCommunicationFailed,
                    "Failed to read complete block from storage. Received {} bytes",
                    read_data.len()
                ));
            }
            let block_start = match start_pos {
                KM_FACTORY_RESET_SECRET_POS => KM_FACTORY_FIRST_SECURE_DELETION_SECRET_POS,
                _ => 0,
            };
            for (chunk_num, secret) in read_data[block_start..].chunks(KM_SECRET_SIZE).enumerate() {
                if (secret[0] & KM_IN_USE_FLAG) == 0 {
                    key_slot =
                        (start_pos + block_start + (chunk_num * KM_SECRET_SIZE)) / KM_SECRET_SIZE;
                    break 'search_loop;
                }
            }
        }
        Ok(key_slot)
    }

    fn write_block(&mut self, start: usize, buffer: &[u8]) -> Result<(), Error> {
        self.transaction.write_at(&mut self.file, start, buffer).map_err(|_| {
            km_err!(
                SecureHwCommunicationFailed,
                "Failed to write to deletion secret file at pos {}",
                start
            )
        })
    }

    fn get_file_size(&mut self) -> Result<usize, Error> {
        self.transaction.get_size(&self.file).map_err(|_| {
            km_err!(SecureHwCommunicationFailed, "Couldn't get secure deletion secret file size")
        })
    }

    fn get_max_file_size(is_upgrade: bool) -> usize {
        match is_upgrade {
            true => KM_MAX_SECRET_FILE_SIZE_FOR_UPGRADES,
            false => KM_MAX_SECRET_FILE_SIZE,
        }
    }

    fn resize(&mut self, new_size: usize) -> Result<(), Error> {
        self.transaction.set_size(&mut self.file, new_size).map_err(|_| {
            km_err!(
                SecureHwCommunicationFailed,
                "Failed to resize secure deletion secret file to {}",
                new_size
            )
        })?;
        Ok(())
    }

    fn zero_entries(&mut self, begin: usize, end: usize) -> Result<(), Error> {
        if (begin % KM_SECRET_SIZE) != 0 {
            return Err(km_err!(
                InvalidArgument,
                "zero_entries called with invalid offset {}",
                begin
            ));
        }
        let zero_buff = [0; KM_SECRET_SIZE];
        for start_pos in (begin..end).step_by(KM_SECRET_SIZE) {
            self.write_block(start_pos, &zero_buff)?;
        }
        Ok(())
    }

    fn finish_transaction(mut self) -> Result<(), Error> {
        self.transaction.commit().map_err(|_| {
            km_err!(
                SecureHwCommunicationFailed,
                "Failed to commit transaction on secure deletion secret file"
            )
        })
    }
}

#[derive(Clone, PartialEq, Eq, Zeroize, ZeroizeOnDrop)]
struct FactoryResetSecret(Option<[u8; KM_FACTORY_RESET_SECRET_SIZE]>);

#[derive(Clone, PartialEq, Eq)]
pub struct TrustySecureDeletionSecretManager {
    factory_reset_secret: RefCell<FactoryResetSecret>,
}

impl TrustySecureDeletionSecretManager {
    pub fn new() -> Self {
        TrustySecureDeletionSecretManager {
            factory_reset_secret: RefCell::new(FactoryResetSecret(None)),
        }
    }

    // get_factory_reset_secret_impl will just try to get the factory reset secret either from cache
    // or from the file if it exists. If the secret is read and not cached, it will cache it.
    // If the file doesn't exist, or if it is empty, it will return a File object/session; so the
    // caller can initialize it. In case the caller doesn't initialize it, we will end up with an
    // empty file on the file system, but this should be fine because we treat an empty file in the
    // same way we treat a non-existing file.
    fn get_factory_reset_secret_impl<'a>(
        &'a self,
        session: Option<&'a mut SecureDeletionSecretFileSession>,
    ) -> Result<RetrieveSecureDeletionSecretFileData, Error> {
        match self.factory_reset_secret.borrow_mut().deref_mut().0 {
            Some(secret) => {
                Ok(RetrieveSecureDeletionSecretFileData::CachedDataFound(SecureDeletionData {
                    factory_reset_secret: secret.clone(),
                    secure_deletion_secret: [0; KM_SECRET_SIZE],
                }))
            }
            mut factory_reset_secret @ None => {
                debug!("Trying to open a session to read factory reset secret");
                let session = session.ok_or(km_err!(
                    SecureHwCommunicationFailed,
                    "Couldn't get a session to open the secure deletion secret file"
                ))?;
                let mut sdsf_file = SecureDeletionSecretFile::open_or_create(session)?;
                let file_size = sdsf_file.get_file_size().map_err(|_| {
                    km_err!(
                        SecureHwCommunicationFailed,
                        "Couldn't get secure deletion secret file size"
                    )
                })?;
                if file_size > 0 {
                    // We found a secret on the file; read it
                    debug!("Opened non-empty secure secrets file");
                    let mut buffer = [0; KM_FACTORY_RESET_SECRET_SIZE];
                    let block = sdsf_file.read_block(KM_FACTORY_RESET_SECRET_POS, &mut buffer)?;
                    debug!("Read factory-reset secret, size {}", block.len());
                    if block.len() != KM_FACTORY_RESET_SECRET_SIZE {
                        return Err(km_err!(
                            SecureHwCommunicationFailed,
                            "Failed to read complete secret data from storage. Received {} bytes",
                            block.len()
                        ));
                    }
                    factory_reset_secret.replace(buffer.clone());
                    Ok(RetrieveSecureDeletionSecretFileData::DataFoundOnFile(SecureDeletionData {
                        factory_reset_secret: buffer,
                        secure_deletion_secret: [0; KM_SECRET_SIZE],
                    }))
                } else {
                    Ok(RetrieveSecureDeletionSecretFileData::EmptyFileFound(sdsf_file))
                }
            }
        }
    }

    // get_or_create_factory_reset_secret_impl will use get_factory_reset_secret_impl to try to get
    // the factory reset secret. If the secure deletion secret file doesn't exist on secure storage,
    // it will create it and will also initialize it.
    fn get_or_create_factory_reset_secret_impl(
        &mut self,
        rng: &mut dyn crypto::Rng,
        wait_for_port: bool,
    ) -> Result<SecureDeletionData, Error> {
        let mut session = SecureDeletionSecretFileSession::new(wait_for_port).ok();
        let mut secret_file_data = self.get_factory_reset_secret_impl(session.as_mut())?;
        match secret_file_data {
            RetrieveSecureDeletionSecretFileData::CachedDataFound(data) => Ok(data),
            RetrieveSecureDeletionSecretFileData::DataFoundOnFile(data) => Ok(data),
            RetrieveSecureDeletionSecretFileData::EmptyFileFound(mut sdsf_file) => {
                sdsf_file.resize(KM_BLOCK_SIZE)?;
                debug!("Resized secure secrets file to size {}", KM_BLOCK_SIZE);
                let mut buffer = [0; KM_FACTORY_RESET_SECRET_SIZE];
                rng.fill_bytes(&mut buffer);
                sdsf_file.write_block(KM_FACTORY_RESET_SECRET_POS, &buffer)?;
                debug!("Wrote new factory reset secret");
                sdsf_file
                    .zero_entries(KM_FACTORY_FIRST_SECURE_DELETION_SECRET_POS, KM_BLOCK_SIZE)?;
                debug!("Zeroed secrets");
                sdsf_file.finish_transaction()?;
                debug!("Committed new secrets file");
                self.factory_reset_secret.borrow_mut().deref_mut().0.replace(buffer.clone());
                Ok(SecureDeletionData {
                    factory_reset_secret: buffer,
                    secure_deletion_secret: [0; KM_SECRET_SIZE],
                })
            }
        }
    }

    fn read_slot_data(&self, slot: SecureDeletionSlot, buffer: &mut [u8]) -> Result<(), Error> {
        let buffer_size = buffer.len();
        if buffer_size != KM_SECRET_SIZE {
            return Err(km_err!(
                InsufficientBufferSpace,
                "Needed {} bytes to read slot. Received {}",
                KM_SECRET_SIZE,
                buffer.len()
            ));
        }
        let requested_slot = slot.0 as usize;
        let key_slot_pos = requested_slot * KM_SECRET_SIZE;
        let mut session = match SecureDeletionSecretFileSession::new(true) {
            Ok(session) => session,
            Err(e) => {
                error!("Failed to open session to get secure deletion data");
                return Err(e);
            }
        };
        let mut sdsf_file = match SecureDeletionSecretFile::open_or_create(&mut session) {
            Ok(sdsf_file) => sdsf_file,
            Err(e) => {
                error!("Failed to open file to get secure deletion data");
                return Err(e);
            }
        };
        let file_size = match sdsf_file.get_file_size() {
            Ok(file_size) => file_size,
            Err(e) => {
                error!("Failed to read secure deletion data file size");
                return Err(e);
            }
        };
        if (key_slot_pos + KM_SECRET_SIZE) > file_size {
            return Err(km_err!(
                InvalidArgument,
                "Invalid key slot {} would read past end of file of size {}",
                requested_slot,
                file_size
            ));
        }
        match sdsf_file.read_block(key_slot_pos, buffer) {
            Ok(read_data) => {
                if buffer_size == read_data.len() {
                    Ok(())
                } else {
                    Err(km_err!(
                        SecureHwCommunicationFailed,
                        "Failed to read complete slot data from storage. Received {} bytes",
                        read_data.len()
                    ))
                }
            }
            Err(e) => {
                error!("Failed to read secret from slot {}", requested_slot);
                Err(e)
            }
        }
    }
}

impl Drop for TrustySecureDeletionSecretManager {
    fn drop(&mut self) {
        self.factory_reset_secret.borrow_mut().deref_mut().zeroize();
    }
}

impl ZeroizeOnDrop for TrustySecureDeletionSecretManager {}

impl SecureDeletionSecretManager for TrustySecureDeletionSecretManager {
    fn get_or_create_factory_reset_secret(
        &mut self,
        rng: &mut dyn crypto::Rng,
    ) -> Result<SecureDeletionData, Error> {
        self.get_or_create_factory_reset_secret_impl(rng, true)
    }

    fn get_factory_reset_secret(&self) -> Result<SecureDeletionData, Error> {
        let mut session = SecureDeletionSecretFileSession::new(true).ok();
        let mut secret_file_data = self.get_factory_reset_secret_impl(session.as_mut())?;
        match secret_file_data {
            RetrieveSecureDeletionSecretFileData::CachedDataFound(data) => Ok(data),
            RetrieveSecureDeletionSecretFileData::DataFoundOnFile(data) => Ok(data),
            RetrieveSecureDeletionSecretFileData::EmptyFileFound(_) => {
                Err(km_err!(UnknownError, "Factory reset secret not found"))
            }
        }
    }

    fn new_secret(
        &mut self,
        rng: &mut dyn crypto::Rng,
        slot_purpose: SlotPurpose,
    ) -> Result<(SecureDeletionSlot, SecureDeletionData), Error> {
        let is_upgrade = match slot_purpose {
            SlotPurpose::KeyUpgrade => true,
            _ => false,
        };
        // We are not waiting on the connection if the TA port is not available. This follows the
        // behavior of the original code.
        let mut secure_deletion_data =
            match self.get_or_create_factory_reset_secret_impl(rng, false) {
                Ok(data) => data,
                Err(e) => {
                    info!("Unable to get factory reset secret");
                    return Err(e);
                }
            };
        rng.fill_bytes(&mut secure_deletion_data.secure_deletion_secret);
        secure_deletion_data.secure_deletion_secret[0] |= KM_IN_USE_FLAG;
        // Next call will block on the port. It should be fine, because if we reach this point, the
        // TA should have been available before. Also, the original code follows a similar flow on
        // which they use a blocking call if this point is reached.
        let mut session = SecureDeletionSecretFileSession::new(true)?;
        let mut sdsf_file = SecureDeletionSecretFile::open_or_create(&mut session)?;
        let mut empty_slot = match sdsf_file.find_empty_slot(is_upgrade) {
            Ok(slot) => slot,
            Err(e) => {
                error!("Error while searching for key slot");
                return Err(e);
            }
        };

        let original_file_size = sdsf_file.get_file_size()?;
        if empty_slot == 0 {
            //No empty slot found, try to increase file size
            let max_file_size = SecureDeletionSecretFile::get_max_file_size(is_upgrade);
            if (original_file_size >= max_file_size) {
                error!(
                    "Didn't find a slot and can't grow the file larger than {}",
                    original_file_size
                );
                return Err(km_err!(
                    UnknownError,
                    "Didn't find a slot and can't grow the file larger than {}",
                    original_file_size
                ));
            }
            let new_size = original_file_size + KM_BLOCK_SIZE;
            debug!("Attempting to resize file from {} to {}", original_file_size, new_size);
            if let Err(e) = sdsf_file.resize(new_size) {
                error!("Failed to grow file to make room for a key slot");
                return Err(e);
            }
            debug!("Resized file to {}", new_size);
            if let Err(e) = sdsf_file.zero_entries(original_file_size, new_size) {
                error!("Error zeroing space in extended file");
                return Err(e);
            }
            empty_slot = original_file_size / KM_SECRET_SIZE;
        }
        debug!("Writing new deletion secret to key slot {}", empty_slot);
        if let Err(e) = sdsf_file
            .write_block(empty_slot * KM_SECRET_SIZE, &secure_deletion_data.secure_deletion_secret)
        {
            error!("Failed to write new deletion secret to key slot {}", empty_slot);
            return Err(e);
        }
        if let Err(e) = sdsf_file.finish_transaction() {
            error!(
                "Failed to commit transaction writing new deletion secret to slot {}",
                empty_slot
            );
            return Err(e);
        }
        debug!("Committed new secret");
        Ok((SecureDeletionSlot(empty_slot as u32), secure_deletion_data))
    }

    fn get_secret(&self, slot: SecureDeletionSlot) -> Result<SecureDeletionData, Error> {
        let mut current_try = 0;
        let mut secure_deletion_data = loop {
            let data = self.get_factory_reset_secret();
            if (data.is_ok()) || (current_try >= KM_MAX_TRIES) {
                break data?;
            }
            current_try += 1;
        };
        let requested_slot = slot.0 as usize;
        // TODO: Should we also limit access to slot 1? slot 1 should be part of the factory reset
        //       secret, but c++ code only checked for slot 0.
        if requested_slot == 0 {
            // Original debug message from c++ code was "Secure deletion not requested"
            debug!("Requested deletion of slot 0 which corresponds to factory reset secret.");
            return Err(km_err!(
                InvalidArgument,
                "Requested slot 0 which does not contain a secret"
            ));
        }

        current_try = 0;
        loop {
            match self.read_slot_data(slot, &mut secure_deletion_data.secure_deletion_secret) {
                Ok(_) => {
                    debug!(
                        "Read secure deletion secret, size: {}",
                        secure_deletion_data.secure_deletion_secret.len()
                    );
                    break Ok(secure_deletion_data);
                }
                Err(e) => {
                    if (current_try >= KM_MAX_TRIES) {
                        break Err(e);
                    }
                }
            }
            current_try += 1;
        }
    }

    fn delete_secret(&mut self, slot: SecureDeletionSlot) -> Result<(), Error> {
        let requested_slot = slot.0 as usize;
        // TODO: Should we also limit access to slot 1? slot 1 should be part of the factory reset
        //       secret, but c++ code only checked for slot 0.
        if requested_slot == 0 {
            debug!("key_slot == 0, nothing to delete");
            return Err(km_err!(
                InvalidArgument,
                "Requested slot 0 which does not contain a secret"
            ));
        }
        let key_slot_start = requested_slot * KM_SECRET_SIZE;
        let key_slot_end = key_slot_start + KM_SECRET_SIZE;
        if (key_slot_start < KM_FACTORY_FIRST_SECURE_DELETION_SECRET_POS) {
            return Err(km_err!(
                InvalidArgument,
                "Attempted to delete invalid key slot {}",
                requested_slot
            ));
        }
        // TODO: Check if we should also stop trying to delete the key after some number of retries.
        //       C++ code doesn't stop retrying, which is the current behavior here.
        loop {
            let mut session = match SecureDeletionSecretFileSession::new(true) {
                Ok(mut session) => session,
                Err(_) => {
                    error!("Failed to open session to retrieve secure deletion data");
                    continue;
                }
            };
            let mut sdsf_file = match SecureDeletionSecretFile::open_or_create(&mut session) {
                Ok(mut sdsf_file) => sdsf_file,
                Err(_) => {
                    error!("Failed to open file to retrieve secure deletion data");
                    continue;
                }
            };
            let file_size = match sdsf_file.get_file_size() {
                Ok(size) => size,
                Err(_) => continue,
            };
            if key_slot_end > file_size {
                return Err(km_err!(
                    InvalidArgument,
                    "Attempted to delete invalid key slot {}",
                    requested_slot
                ));
            }
            if let Err(_) = sdsf_file.zero_entries(key_slot_start, key_slot_end) {
                continue;
            }
            debug!(
                "Deleted secure key slot {}, zeroing {} to {}",
                requested_slot, key_slot_start, key_slot_end
            );
            if let Err(_) = sdsf_file.finish_transaction() {
                error!("Failed to commit transaction deleting key at slot {}", requested_slot);
                continue;
            }
            debug!("Committed deletion");
            break;
        }
        Ok(())
    }

    fn delete_all(&mut self) {
        // TODO: Check if we should also stop trying to delete all keys after some number of
        //       retries. C++ code doesn't stop retrying, which is the current behavior here.
        loop {
            let mut session = match SecureDeletionSecretFileSession::new(true) {
                Ok(mut session) => session,
                Err(_) => {
                    error!("Failed to open session to delete secrets file");
                    continue;
                }
            };
            if session.delete_file().is_ok() {
                break;
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use kmr_crypto_boring::rng::BoringRng;
    use test::{expect, expect_eq, expect_ne};

    fn check_secret_manager_file_exists() -> bool {
        let mut session =
            Session::new(Port::TamperProof, true).expect("Couldn't connect to storage");
        session.open_file(KM_SECURE_DELETION_SECRET_FILENAME, OpenMode::Open).is_ok()
    }

    #[test]
    fn secret_data_is_cached() {
        let mut sdsf = TrustySecureDeletionSecretManager::new();
        sdsf.delete_all();
        expect!(check_secret_manager_file_exists() == false, "Couldn't delete secret manager file");
        let mut rng = BoringRng::default();
        let secret1 =
            sdsf.get_or_create_factory_reset_secret(&mut rng).expect("Couldn't create secret");
        let mut session = SecureDeletionSecretFileSession::new(true).ok();
        let secret2 = match sdsf.get_factory_reset_secret_impl(session.as_mut()) {
            Ok(RetrieveSecureDeletionSecretFileData::CachedDataFound(secret)) => secret,
            _ => panic!("Data should have been cached"),
        };
        let secret3 =
            sdsf.get_or_create_factory_reset_secret(&mut rng).expect("Couldn't get secret");
        expect_eq!(
            secret1.factory_reset_secret,
            secret2.factory_reset_secret,
            "Should have retrieved the same secret"
        );
        expect_eq!(
            secret1.secure_deletion_secret,
            secret2.secure_deletion_secret,
            "Should have retrieved the same secret"
        );
        expect_eq!(
            secret1.secure_deletion_secret,
            [0; KM_SECRET_SIZE],
            "Deletion secret should be 0"
        );
        expect_ne!(
            secret1.factory_reset_secret,
            [0; KM_FACTORY_RESET_SECRET_SIZE],
            "Factory reset secret should not be 0"
        );
        expect_eq!(
            secret1.factory_reset_secret,
            secret3.factory_reset_secret,
            "Should have retrieved the same secret"
        );
        sdsf.factory_reset_secret.replace(FactoryResetSecret(None));
        let secret3 = match sdsf.get_factory_reset_secret_impl(session.as_mut()) {
            Ok(RetrieveSecureDeletionSecretFileData::DataFoundOnFile(secret)) => secret,
            _ => panic!("Data couldn't be read from file."),
        };
        expect_eq!(
            secret1.factory_reset_secret,
            secret3.factory_reset_secret,
            "Should have retrieved the same secret"
        );
        sdsf.delete_all();
        expect!(check_secret_manager_file_exists() == false, "Couldn't delete secret manager file");
    }

    #[test]
    fn new_secret_data_file_is_clean() {
        let mut sdsf = TrustySecureDeletionSecretManager::new();
        sdsf.delete_all();
        expect!(check_secret_manager_file_exists() == false, "Couldn't delete secret manager file");
        let mut rng = BoringRng::default();
        let secret1 =
            sdsf.get_or_create_factory_reset_secret(&mut rng).expect("Couldn't create secret");
        let num_initial_slots = KM_BLOCK_SIZE / KM_SECRET_SIZE;
        for slot_num in (2..num_initial_slots) {
            let secret =
                sdsf.get_secret(SecureDeletionSlot(slot_num as u32)).expect("Couldn't read slot");
            expect_eq!(
                secret.secure_deletion_secret,
                [0; KM_SECRET_SIZE],
                "Deletion secret should be 0"
            );
            expect_eq!(
                secret.factory_reset_secret,
                secret1.factory_reset_secret,
                "Factory reset secret should match"
            );
        }
        let secret = sdsf.get_secret(SecureDeletionSlot(num_initial_slots as u32));
        expect!(secret.is_err(), "Read outside of initial range should fail");
        sdsf.delete_all();
        expect!(check_secret_manager_file_exists() == false, "Couldn't delete secret manager file");
    }

    #[test]
    fn new_secret_data_file_expands() {
        let mut sdsf = TrustySecureDeletionSecretManager::new();
        sdsf.delete_all();
        expect!(check_secret_manager_file_exists() == false, "Couldn't delete secret manager file");
        let mut rng = BoringRng::default();
        let secret1 =
            sdsf.get_or_create_factory_reset_secret(&mut rng).expect("Couldn't create secret");
        let num_slots_per_block = KM_BLOCK_SIZE / KM_SECRET_SIZE;
        let max_num_slots = KM_MAX_SECRET_FILE_SIZE / KM_SECRET_SIZE;
        for slot_num in (2..max_num_slots) {
            let (deletion_slot, deletion_data) = sdsf
                .new_secret(&mut rng, SlotPurpose::KeyGeneration)
                .expect("Couldn't create secret");
            // This test assumes order of secret creation on an empty file; next line can be changed
            // to something like a map (to check that an empty slot if chosen every time) if order
            // is not sequential anymore.
            expect_eq!(deletion_slot.0 as usize, slot_num, "Wrong slot used for new secret");
            expect_ne!(
                deletion_data.secure_deletion_secret,
                [0; KM_SECRET_SIZE],
                "Deletion secret should not be 0"
            );
            expect_ne!(
                deletion_data.secure_deletion_secret[0] & KM_IN_USE_FLAG,
                0,
                "Slot should be marked as in use"
            );
            let slot_data = sdsf.get_secret(deletion_slot).expect("Couldn't read back secret");
            expect_eq!(
                deletion_data.secure_deletion_secret,
                slot_data.secure_deletion_secret,
                "Secret data should match"
            );
            expect_eq!(
                deletion_data.factory_reset_secret,
                slot_data.factory_reset_secret,
                "Factory reset secret should match"
            );
        }
        let size_failure = sdsf.new_secret(&mut rng, SlotPurpose::KeyGeneration);
        expect!(size_failure.is_err(), "Shouldn't be able to increase secret file size any larger");
        //Testing upgrade flow
        let max_num_upgrade_slots = (KM_MAX_SECRET_FILE_SIZE_FOR_UPGRADES) / KM_SECRET_SIZE;
        for slot_num in (max_num_slots..max_num_upgrade_slots) {
            let (deletion_slot, deletion_data) = sdsf
                .new_secret(&mut rng, SlotPurpose::KeyUpgrade)
                .expect("Couldn't create secret for upgrade flow");
            expect_eq!(deletion_slot.0 as usize, slot_num, "Wrong slot used for new secret");
            expect_ne!(
                deletion_data.secure_deletion_secret,
                [0; KM_SECRET_SIZE],
                "Deletion secret should not be 0"
            );
            expect_ne!(
                deletion_data.secure_deletion_secret[0] & KM_IN_USE_FLAG,
                0,
                "Slot should be marked as in use"
            );
            let slot_data = sdsf.get_secret(deletion_slot).expect("Couldn't read back secret");
            expect_eq!(
                deletion_data.secure_deletion_secret,
                slot_data.secure_deletion_secret,
                "Secret data should match"
            );
            expect_eq!(
                deletion_data.factory_reset_secret,
                slot_data.factory_reset_secret,
                "Factory reset secret should match"
            );
        }
        let size_failure = sdsf.new_secret(&mut rng, SlotPurpose::KeyUpgrade);
        expect!(size_failure.is_err(), "Shouldn't be able to increase secret file size any larger");
        //Testing deletion
        for slot_num in (2..max_num_upgrade_slots).rev() {
            let slot = SecureDeletionSlot(slot_num as u32);
            sdsf.delete_secret(slot).expect("Couldn't delete secret");
            let slot_data = sdsf.get_secret(slot).expect("Couldn't read back secret");
            expect_eq!(
                slot_data.secure_deletion_secret,
                [0; KM_SECRET_SIZE],
                "Deletion secret should be 0"
            );
            let (deletion_slot, deletion_data) =
                sdsf.new_secret(&mut rng, SlotPurpose::KeyUpgrade).expect("Couldn't create secret");
            expect_eq!(deletion_slot.0 as usize, slot_num, "Wrong slot used for new secret");
            expect_ne!(
                deletion_data.secure_deletion_secret,
                [0; KM_SECRET_SIZE],
                "Deletion secret should not be 0"
            );
            expect_ne!(
                deletion_data.secure_deletion_secret[0] & KM_IN_USE_FLAG,
                0,
                "Slot should be marked as in use"
            );
        }
        sdsf.delete_all();
        expect!(check_secret_manager_file_exists() == false, "Couldn't delete secret manager file");
    }

    #[test]
    fn new_secret_data_dont_affect_neighbors() {
        let mut sdsf = TrustySecureDeletionSecretManager::new();
        sdsf.delete_all();
        expect!(check_secret_manager_file_exists() == false, "Couldn't delete secret manager file");
        let mut rng = BoringRng::default();
        let reset_secret = sdsf
            .get_or_create_factory_reset_secret(&mut rng)
            .expect("Couldn't create factory reset secret");
        let (deletion_slot_1, deletion_data_1) =
            sdsf.new_secret(&mut rng, SlotPurpose::KeyGeneration).expect("Couldn't create secret");
        sdsf.delete_secret(deletion_slot_1).expect("Couldn't delete secret");
        // Delete cached data
        sdsf.factory_reset_secret.replace(FactoryResetSecret(None));
        let reset_secret_1 =
            sdsf.get_factory_reset_secret().expect("Couldn't get factory reset secret");
        expect_eq!(
            reset_secret.factory_reset_secret,
            reset_secret_1.factory_reset_secret,
            "Factory reset secret should match"
        );
        let (deletion_slot_1, deletion_data_1) =
            sdsf.new_secret(&mut rng, SlotPurpose::KeyGeneration).expect("Couldn't create secret");
        let (deletion_slot_2, deletion_data_2) =
            sdsf.new_secret(&mut rng, SlotPurpose::KeyGeneration).expect("Couldn't create secret");
        let (deletion_slot_3, deletion_data_3) =
            sdsf.new_secret(&mut rng, SlotPurpose::KeyGeneration).expect("Couldn't create secret");
        let (deletion_slot_4, deletion_data_4) =
            sdsf.new_secret(&mut rng, SlotPurpose::KeyGeneration).expect("Couldn't create secret");
        let (deletion_slot_5, deletion_data_5) =
            sdsf.new_secret(&mut rng, SlotPurpose::KeyGeneration).expect("Couldn't create secret");
        let slot_data = sdsf.get_secret(deletion_slot_1).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_1.secure_deletion_secret,
            "Secret data should match"
        );
        let slot_data = sdsf.get_secret(deletion_slot_2).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_2.secure_deletion_secret,
            "Secret data should match"
        );
        let slot_data = sdsf.get_secret(deletion_slot_3).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_3.secure_deletion_secret,
            "Secret data should match"
        );
        let slot_data = sdsf.get_secret(deletion_slot_4).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_4.secure_deletion_secret,
            "Secret data should match"
        );
        let slot_data = sdsf.get_secret(deletion_slot_5).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_5.secure_deletion_secret,
            "Secret data should match"
        );
        sdsf.delete_secret(deletion_slot_3).expect("Couldn't delete secret");
        let slot_data = sdsf.get_secret(deletion_slot_1).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_1.secure_deletion_secret,
            "Secret data should match"
        );
        let slot_data = sdsf.get_secret(deletion_slot_2).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_2.secure_deletion_secret,
            "Secret data should match"
        );
        let slot_data = sdsf.get_secret(deletion_slot_3).expect("Couldn't read back secret");
        expect_ne!(
            slot_data.secure_deletion_secret,
            deletion_data_3.secure_deletion_secret,
            "Secret data should not match anymore"
        );
        let slot_data = sdsf.get_secret(deletion_slot_4).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_4.secure_deletion_secret,
            "Secret data should match"
        );
        let slot_data = sdsf.get_secret(deletion_slot_5).expect("Couldn't read back secret");
        expect_eq!(
            slot_data.secure_deletion_secret,
            deletion_data_5.secure_deletion_secret,
            "Secret data should match"
        );
        // Delete cached data
        sdsf.factory_reset_secret.replace(FactoryResetSecret(None));
        let reset_secret_1 =
            sdsf.get_factory_reset_secret().expect("Couldn't get factory reset secret");
        expect_eq!(
            reset_secret.factory_reset_secret,
            reset_secret_1.factory_reset_secret,
            "Factory reset secret should match"
        );
        sdsf.delete_all();
        expect!(check_secret_manager_file_exists() == false, "Couldn't delete secret manager file");
    }
}

/// Wrapper to allow a single instance of [`SecureDeletionSecretManager`] to be shared.
#[derive(Clone)]
pub struct SharedSddManager<T> {
    inner: Rc<RefCell<T>>,
}

impl<T> SharedSddManager<T> {
    /// Move a [`SecureDeletionSecretManager`] into a shareable wrapper.
    pub fn new(inner: T) -> Self {
        Self { inner: Rc::new(RefCell::new(inner)) }
    }
}

impl<T: SecureDeletionSecretManager> SecureDeletionSecretManager for SharedSddManager<T> {
    fn get_or_create_factory_reset_secret(
        &mut self,
        rng: &mut dyn crypto::Rng,
    ) -> Result<SecureDeletionData, Error> {
        self.inner.borrow_mut().get_or_create_factory_reset_secret(rng)
    }

    fn get_factory_reset_secret(&self) -> Result<SecureDeletionData, Error> {
        self.inner.borrow_mut().get_factory_reset_secret()
    }

    fn new_secret(
        &mut self,
        rng: &mut dyn crypto::Rng,
        purpose: kmr_common::keyblob::SlotPurpose,
    ) -> Result<(SecureDeletionSlot, SecureDeletionData), Error> {
        self.inner.borrow_mut().new_secret(rng, purpose)
    }

    fn get_secret(&self, slot: SecureDeletionSlot) -> Result<SecureDeletionData, Error> {
        self.inner.borrow().get_secret(slot)
    }

    fn delete_secret(&mut self, slot: SecureDeletionSlot) -> Result<(), Error> {
        self.inner.borrow_mut().delete_secret(slot)
    }

    fn delete_all(&mut self) {
        self.inner.borrow_mut().delete_all()
    }
}
