From e0f75ab97efe3ef241d1bb7cdf83e092d64c5d27 Mon Sep 17 00:00:00 2001 From: Karolin Varner Date: Sat, 13 Jan 2024 23:14:43 +0100 Subject: [PATCH] feat: Use xchacha implementation from rust crypto instead of sodium --- ciphers/src/lib.rs | 2 +- ciphers/src/subtle/mod.rs | 1 + ciphers/src/subtle/xchacha20poly1305_ietf.rs | 45 ++++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 ciphers/src/subtle/xchacha20poly1305_ietf.rs diff --git a/ciphers/src/lib.rs b/ciphers/src/lib.rs index 252ae61..6ee1934 100644 --- a/ciphers/src/lib.rs +++ b/ciphers/src/lib.rs @@ -16,7 +16,7 @@ pub mod aead { /// Authenticated encryption with associated data with a constant nonce pub mod xaead { - pub use rosenpass_sodium::aead::xchacha20poly1305_ietf::{ + pub use crate::subtle::xchacha20poly1305_ietf::{ decrypt, encrypt, KEY_LEN, NONCE_LEN, TAG_LEN, }; } diff --git a/ciphers/src/subtle/mod.rs b/ciphers/src/subtle/mod.rs index 70c9425..782272b 100644 --- a/ciphers/src/subtle/mod.rs +++ b/ciphers/src/subtle/mod.rs @@ -1,2 +1,3 @@ pub mod incorrect_hmac_blake2b; pub mod chacha20poly1305_ietf; +pub mod xchacha20poly1305_ietf; diff --git a/ciphers/src/subtle/xchacha20poly1305_ietf.rs b/ciphers/src/subtle/xchacha20poly1305_ietf.rs new file mode 100644 index 0000000..64c349e --- /dev/null +++ b/ciphers/src/subtle/xchacha20poly1305_ietf.rs @@ -0,0 +1,45 @@ +use rosenpass_to::To; +use rosenpass_to::ops::copy_slice; +use rosenpass_util::typenum2const; + +use chacha20poly1305::aead::generic_array::GenericArray; +use chacha20poly1305::{XChaCha20Poly1305 as AeadImpl}; +use chacha20poly1305::{AeadCore, KeySizeUser, KeyInit, AeadInPlace}; + +pub const KEY_LEN: usize = typenum2const! { ::KeySize }; +pub const TAG_LEN: usize = typenum2const! { ::TagSize }; +pub const NONCE_LEN: usize = typenum2const! { ::NonceSize }; + +#[inline] +pub fn encrypt( + ciphertext: &mut [u8], + key: &[u8], + nonce: &[u8], + ad: &[u8], + plaintext: &[u8], +) -> anyhow::Result<()> { + let nonce = GenericArray::from_slice(nonce); + let (n, ct_mac) = ciphertext.split_at_mut(NONCE_LEN); + let (ct, mac) = ct_mac.split_at_mut(ct_mac.len() - TAG_LEN); + copy_slice(nonce).to(n); + copy_slice(plaintext).to(ct); + let mac_value = AeadImpl::new_from_slice(key)?.encrypt_in_place_detached(&nonce, ad, ct)?; + copy_slice(&mac_value[..]).to(mac); + Ok(()) +} + +#[inline] +pub fn decrypt( + plaintext: &mut [u8], + key: &[u8], + ad: &[u8], + ciphertext: &[u8], +) -> anyhow::Result<()> { + let (n, ct_mac) = ciphertext.split_at(NONCE_LEN); + let (ct, mac) = ct_mac.split_at(ct_mac.len() - TAG_LEN); + let nonce = GenericArray::from_slice(n); + let tag = GenericArray::from_slice(mac); + copy_slice(ct).to(plaintext); + AeadImpl::new_from_slice(key)?.decrypt_in_place_detached(&nonce, ad, plaintext, tag)?; + Ok(()) +}