skymd 0.1.10

Rust bindings for hacl*
use crate::ffi::{
    EverCrypt_Chacha20Poly1305_aead_decrypt, EverCrypt_Chacha20Poly1305_aead_encrypt,
};

pub const KEY_LEN: usize = 32;
pub const TAG_LEN: usize = 16;
pub const NONCE_LEN: usize = 24;

pub fn decrypt(
    key: &[u8; KEY_LEN],
    nonce: &[u8; NONCE_LEN],
    associated_data: &[u8],
    plaintext: &mut [u8],
    ciphertext: &[u8],
    tag: &[u8; TAG_LEN],
) -> Result<(), ()> {
    let res = unsafe {
        EverCrypt_Chacha20Poly1305_aead_decrypt(
            key.as_ptr(),
            nonce.as_ptr(),
            associated_data.len() as u32,
            associated_data.as_ptr(),
            ciphertext.len() as u32,
            plaintext.as_mut_ptr(),
            ciphertext.as_ptr(),
            tag.as_ptr(),
        )
    };

    match res {
        0 => Ok(()),
        _ => Err(()),
    }
}

pub fn encrypt(
    key: &[u8; KEY_LEN],
    nonce: &[u8; NONCE_LEN],
    associated_data: &[u8],
    plaintext: &[u8],
    ciphertext: &mut [u8],
    tag: &mut [u8; TAG_LEN],
) {
    unsafe {
        EverCrypt_Chacha20Poly1305_aead_encrypt(
            key.as_ptr(),
            nonce.as_ptr(),
            associated_data.len() as u32,
            associated_data.as_ptr(),
            plaintext.len() as u32,
            plaintext.as_ptr(),
            ciphertext.as_mut_ptr(),
            tag.as_mut_ptr(),
        )
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn encrypt_test() {
        crate::skymd_init();
        let key = [1; KEY_LEN];
        let nonce = [1; NONCE_LEN];
        let associated_data = [1; 10];
        let plaintext = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
        let mut decrypted = [0; 10];
        let mut ciphertext = [0; 10];
        let mut tag = [0; TAG_LEN];

        encrypt(
            &key,
            &nonce,
            &associated_data,
            &plaintext,
            &mut ciphertext,
            &mut tag,
        );

        let res = decrypt(
            &key,
            &nonce,
            &associated_data,
            &mut decrypted,
            &ciphertext,
            &tag,
        );

        assert!(res.is_ok());
        assert_eq!(&plaintext, &decrypted);
    }
}