spacedls 0.4.0

no_std CCSDS 355.0-B-2 (SDLS) Space Data Link Security implementation
Documentation
use core::fmt;
use core::ops::{Deref, DerefMut};
use ctutils::{Choice, CtEq};
use hybrid_array::{Array, ArraySize};

/// Fixed-size Message Authentication Code.
///
/// Comparison uses constant-time equality via `CtEq`.
#[derive(Clone, Debug)]
pub struct Mac<N: ArraySize>(Array<u8, N>);

impl<N: ArraySize> CtEq for Mac<N> {
    fn ct_eq(&self, other: &Self) -> Choice { self.0.as_slice().ct_eq(other.0.as_slice()) }
}

impl<N: ArraySize> Deref for Mac<N> {
    type Target = Array<u8, N>;
    #[inline]
    fn deref(&self) -> &Self::Target { &self.0 }
}

impl<N: ArraySize> DerefMut for Mac<N> {
    #[inline]
    fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 }
}

impl<N: ArraySize> From<Array<u8, N>> for Mac<N> {
    #[inline]
    fn from(t: Array<u8, N>) -> Self { Mac(t) }
}

/// Outcome of a MAC verification operation.
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VerifyMacResult {
    /// MAC matches and has full length.
    Ok,
    /// MAC matches but is shorter than the algorithm's native output
    /// (CCSDS 355.0-B-2 Section 4.2.3.4).
    OkButTruncated,
    /// MAC does not match; the frame should be discarded.
    InvalidMac,
}

impl fmt::Display for VerifyMacResult {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::Ok => write!(f, "MAC valid"),
            Self::OkButTruncated => write!(f, "MAC valid (truncated)"),
            Self::InvalidMac => write!(f, "MAC invalid"),
        }
    }
}