anubis-age 1.4.0

Post-quantum secure encryption library with hybrid X25519+ML-KEM-1024 mode (internal dependency for anubis-rage)
Documentation
//! Primitive cryptographic operations used by `age`.

use anubis_core::secrecy::{ExposeSecret, SecretBox};
use hmac::{
    digest::{CtOutput, MacError},
    Hmac, Mac,
};
use sha2::Sha512;
use std::io::{self, Write};

#[cfg(feature = "armor")]
#[cfg_attr(docsrs, doc(cfg(feature = "armor")))]
pub mod armor;

pub mod stream;

pub mod aead;

pub(crate) struct HmacKey(pub(crate) SecretBox<[u8; 64]>);

/// `HMAC[key](message)`
///
/// HMAC from [RFC 2104] with SHA-512 for NIST Level-5 security.
///
/// [RFC 2104]: https://tools.ietf.org/html/rfc2104
pub(crate) struct HmacWriter {
    inner: Hmac<Sha512>,
}

impl HmacWriter {
    /// Constructs a new writer to process input data.
    pub(crate) fn new(key: HmacKey) -> Self {
        HmacWriter {
            inner: Hmac::new_from_slice(key.0.expose_secret()).expect("key is the correct length"),
        }
    }

    /// Checks if `mac` is correct for the processed input.
    pub(crate) fn finalize(self) -> CtOutput<Hmac<Sha512>> {
        self.inner.finalize()
    }

    /// Checks if `mac` is correct for the processed input.
    pub(crate) fn verify(self, mac: &[u8]) -> Result<(), MacError> {
        self.inner.verify_slice(mac)
    }
}

impl Write for HmacWriter {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        self.inner.update(data);
        Ok(data.len())
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}