liboxyd 0.1.4

Coldwire's cryptographic library
Documentation
use chacha20poly1305::{aead::KeyInit, AeadInPlace, Tag, XChaCha20Poly1305, XNonce};

use crate::v1::utils::EMPTY_BYTES;

use super::utils::{generate_nonce, CHACHA_NONCE_LENGTH, CHACHA_NONCE_PLUS_TAG_LENGTH};

pub async fn encrypt(data: &[u8], key: &[u8]) -> Option<Vec<u8>> {
    let aead = XChaCha20Poly1305::new(key.as_ref().into());
    let nonce = generate_nonce();

    let mut out = Vec::with_capacity(data.len());
    out.extend(data);

    match aead.encrypt_in_place_detached(&nonce, &EMPTY_BYTES, &mut out) {
        Ok(tag) => {
            let mut output = Vec::with_capacity(CHACHA_NONCE_PLUS_TAG_LENGTH + data.len());
            output.extend(nonce);
            output.extend(tag);
            output.extend(out);
            Some(output)
        }
        Err(_) => return None,
    }
}

pub async fn decrypt(data: &[u8], key: &[u8]) -> Option<Vec<u8>> {
    if data.len() < CHACHA_NONCE_PLUS_TAG_LENGTH {
        return None;
    }

    let aead = XChaCha20Poly1305::new(key.as_ref().into());

    let nonce = XNonce::from_slice(&data[..CHACHA_NONCE_LENGTH]);
    let tag = Tag::from_slice(&data[CHACHA_NONCE_LENGTH..CHACHA_NONCE_PLUS_TAG_LENGTH]);

    let mut out = Vec::with_capacity(data.len() - CHACHA_NONCE_PLUS_TAG_LENGTH);
    out.extend(&data[CHACHA_NONCE_PLUS_TAG_LENGTH..]);

    match aead.decrypt_in_place_detached(nonce.into(), &EMPTY_BYTES, &mut out, tag) {
        Ok(_) => Some(out),
        Err(_) => None,
    }
}