insectbox 0.1.0

OpenSSH inspired in-memory key security.
Documentation
use ascon_aead::aead::Buffer;
use ascon_aead::aead::Error;
use ascon_aead::aead::Result;

use crate::utils;

#[derive(Debug)]
pub struct PageVec {
    pub ptr: *mut u8,
    pub len: usize,
}
// for all the following:
// SAFETY: we ensure all the requirements when constructing a PageVec,
// plus this type is not public (because of the module being private)
impl AsRef<[u8]> for PageVec {
    fn as_ref(&self) -> &[u8] {
        unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
    }
}

impl AsMut<[u8]> for PageVec {
    fn as_mut(&mut self) -> &mut [u8] {
        unsafe { std::slice::from_raw_parts_mut(self.ptr, self.len) }
    }
}

impl Buffer for PageVec {
    fn extend_from_slice(&mut self, other: &[u8]) -> Result<()> {
        if self.len + other.len() > *utils::PAGE_SIZE {
            Err(Error)
        } else {
            // SAFETY: we check for the length requirement before AND
            // the allocation spans the entire page (nothing is uninit)
            unsafe {
                let start = self.ptr.add(self.len);
                // as discussed before, we definitely have room for this
                let sl = std::slice::from_raw_parts_mut(start, other.len());
                for (dst, val) in sl.iter_mut().zip(other) {
                    *dst = *val;
                }
            }
            self.len += other.len();
            Ok(())
        }
    }

    fn truncate(&mut self, len: usize) {
        unsafe {
            let truncate_start = self.ptr.add(len);
            // zero out the cut-off data
            utils::memzero(truncate_start, self.len - len);
        }
        self.len = len;
    }
}