mirror of
https://github.com/rosenpass/rosenpass.git
synced 2026-02-27 22:13:12 -08:00
chore: Move xchacha20 implementation out of rosenpass::sodium
This commit is contained in:
committed by
Karolin Varner
parent
c64e721c2f
commit
3ddf736b60
@@ -3,6 +3,7 @@ resolver = "2"
|
|||||||
|
|
||||||
members = [
|
members = [
|
||||||
"rosenpass",
|
"rosenpass",
|
||||||
|
"rosenpass-ciphers",
|
||||||
"rosenpass-util",
|
"rosenpass-util",
|
||||||
"rosenpass-constant-time",
|
"rosenpass-constant-time",
|
||||||
"rosenpass-sodium",
|
"rosenpass-sodium",
|
||||||
|
|||||||
@@ -3,3 +3,9 @@ pub mod aead {
|
|||||||
decrypt, encrypt, KEY_LEN, NONCE_LEN, TAG_LEN,
|
decrypt, encrypt, KEY_LEN, NONCE_LEN, TAG_LEN,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod xaead {
|
||||||
|
pub use rosenpass_sodium::aead::xchacha20poly1305_ietf::{
|
||||||
|
decrypt, encrypt, KEY_LEN, NONCE_LEN, TAG_LEN,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
pub mod chacha20poly1305_ietf;
|
pub mod chacha20poly1305_ietf;
|
||||||
|
pub mod xchacha20poly1305_ietf;
|
||||||
|
|||||||
63
rosenpass-sodium/src/aead/xchacha20poly1305_ietf.rs
Normal file
63
rosenpass-sodium/src/aead/xchacha20poly1305_ietf.rs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
use libsodium_sys as libsodium;
|
||||||
|
use std::ffi::c_ulonglong;
|
||||||
|
use std::ptr::{null, null_mut};
|
||||||
|
|
||||||
|
pub const KEY_LEN: usize = libsodium::crypto_aead_xchacha20poly1305_IETF_KEYBYTES as usize;
|
||||||
|
pub const TAG_LEN: usize = libsodium::crypto_aead_xchacha20poly1305_ietf_ABYTES as usize;
|
||||||
|
pub const NONCE_LEN: usize = libsodium::crypto_aead_xchacha20poly1305_IETF_NPUBBYTES as usize;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn encrypt(
|
||||||
|
ciphertext: &mut [u8],
|
||||||
|
key: &[u8],
|
||||||
|
nonce: &[u8],
|
||||||
|
ad: &[u8],
|
||||||
|
plaintext: &[u8],
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
assert!(ciphertext.len() == plaintext.len() + NONCE_LEN + TAG_LEN);
|
||||||
|
assert!(key.len() == libsodium::crypto_aead_xchacha20poly1305_IETF_KEYBYTES as usize);
|
||||||
|
let (n, ct) = ciphertext.split_at_mut(NONCE_LEN);
|
||||||
|
n.copy_from_slice(nonce);
|
||||||
|
let mut clen: u64 = 0;
|
||||||
|
sodium_call!(
|
||||||
|
crypto_aead_xchacha20poly1305_ietf_encrypt,
|
||||||
|
ct.as_mut_ptr(),
|
||||||
|
&mut clen,
|
||||||
|
plaintext.as_ptr(),
|
||||||
|
plaintext.len() as c_ulonglong,
|
||||||
|
ad.as_ptr(),
|
||||||
|
ad.len() as c_ulonglong,
|
||||||
|
null(), // nsec is not used
|
||||||
|
nonce.as_ptr(),
|
||||||
|
key.as_ptr()
|
||||||
|
)?;
|
||||||
|
assert!(clen as usize == ct.len());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn decrypt(
|
||||||
|
plaintext: &mut [u8],
|
||||||
|
key: &[u8],
|
||||||
|
ad: &[u8],
|
||||||
|
ciphertext: &[u8],
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
assert!(ciphertext.len() == plaintext.len() + NONCE_LEN + TAG_LEN);
|
||||||
|
assert!(key.len() == KEY_LEN);
|
||||||
|
let (n, ct) = ciphertext.split_at(NONCE_LEN);
|
||||||
|
let mut mlen: u64 = 0;
|
||||||
|
sodium_call!(
|
||||||
|
crypto_aead_xchacha20poly1305_ietf_decrypt,
|
||||||
|
plaintext.as_mut_ptr(),
|
||||||
|
&mut mlen as *mut c_ulonglong,
|
||||||
|
null_mut(), // nsec is not used
|
||||||
|
ct.as_ptr(),
|
||||||
|
ct.len() as c_ulonglong,
|
||||||
|
ad.as_ptr(),
|
||||||
|
ad.len() as c_ulonglong,
|
||||||
|
n.as_ptr(),
|
||||||
|
key.as_ptr()
|
||||||
|
)?;
|
||||||
|
assert!(mlen as usize == plaintext.len());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
|
|
||||||
use super::RosenpassError;
|
use super::RosenpassError;
|
||||||
use crate::{pqkem::*, sodium};
|
use crate::{pqkem::*, sodium};
|
||||||
use rosenpass_ciphers::aead;
|
use rosenpass_ciphers::{aead, xaead};
|
||||||
|
|
||||||
// Macro magic ////////////////////////////////////////////////////////////////
|
// Macro magic ////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ impl TryFrom<u8> for MsgType {
|
|||||||
pub const BISCUIT_PT_LEN: usize = Biscuit::<()>::LEN;
|
pub const BISCUIT_PT_LEN: usize = Biscuit::<()>::LEN;
|
||||||
|
|
||||||
/// Length in bytes of an encrypted Biscuit (cipher text)
|
/// Length in bytes of an encrypted Biscuit (cipher text)
|
||||||
pub const BISCUIT_CT_LEN: usize = BISCUIT_PT_LEN + sodium::XAEAD_NONCE_LEN + sodium::XAEAD_TAG_LEN;
|
pub const BISCUIT_CT_LEN: usize = BISCUIT_PT_LEN + xaead::NONCE_LEN + xaead::TAG_LEN;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_constants {
|
mod test_constants {
|
||||||
@@ -393,6 +393,7 @@ mod test_constants {
|
|||||||
msgs::{BISCUIT_CT_LEN, BISCUIT_PT_LEN},
|
msgs::{BISCUIT_CT_LEN, BISCUIT_PT_LEN},
|
||||||
sodium,
|
sodium,
|
||||||
};
|
};
|
||||||
|
use rosenpass_ciphers::xaead;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sodium_keysize() {
|
fn sodium_keysize() {
|
||||||
@@ -408,7 +409,7 @@ mod test_constants {
|
|||||||
fn biscuit_ct_len() {
|
fn biscuit_ct_len() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
BISCUIT_CT_LEN,
|
BISCUIT_CT_LEN,
|
||||||
BISCUIT_PT_LEN + sodium::XAEAD_NONCE_LEN + sodium::XAEAD_TAG_LEN
|
BISCUIT_PT_LEN + xaead::NONCE_LEN + xaead::TAG_LEN
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ use crate::{
|
|||||||
sodium::*,
|
sodium::*,
|
||||||
};
|
};
|
||||||
use anyhow::{bail, ensure, Context, Result};
|
use anyhow::{bail, ensure, Context, Result};
|
||||||
use rosenpass_ciphers::aead;
|
use rosenpass_ciphers::{aead, xaead};
|
||||||
use rosenpass_util::{cat, mem::cpy_min, ord::max_usize, time::Timebase};
|
use rosenpass_util::{cat, mem::cpy_min, ord::max_usize, time::Timebase};
|
||||||
use std::collections::hash_map::{
|
use std::collections::hash_map::{
|
||||||
Entry::{Occupied, Vacant},
|
Entry::{Occupied, Vacant},
|
||||||
@@ -152,7 +152,7 @@ pub type PeerId = Public<KEY_SIZE>;
|
|||||||
pub type SessionId = Public<SESSION_ID_LEN>;
|
pub type SessionId = Public<SESSION_ID_LEN>;
|
||||||
pub type BiscuitId = Public<BISCUIT_ID_LEN>;
|
pub type BiscuitId = Public<BISCUIT_ID_LEN>;
|
||||||
|
|
||||||
pub type XAEADNonce = Public<XAEAD_NONCE_LEN>;
|
pub type XAEADNonce = Public<{ xaead::NONCE_LEN }>;
|
||||||
|
|
||||||
pub type MsgBuf = Public<MAX_MESSAGE_LEN>;
|
pub type MsgBuf = Public<MAX_MESSAGE_LEN>;
|
||||||
|
|
||||||
@@ -1309,7 +1309,7 @@ impl HandshakeState {
|
|||||||
|
|
||||||
let k = bk.get(srv).key.secret();
|
let k = bk.get(srv).key.secret();
|
||||||
let pt = biscuit.all_bytes();
|
let pt = biscuit.all_bytes();
|
||||||
xaead_enc_into(biscuit_ct, k, &*n, &ad, pt)?;
|
xaead::encrypt(biscuit_ct, k, &*n, &ad, pt)?;
|
||||||
|
|
||||||
self.mix(biscuit_ct)
|
self.mix(biscuit_ct)
|
||||||
}
|
}
|
||||||
@@ -1335,7 +1335,7 @@ impl HandshakeState {
|
|||||||
// Allocate and decrypt the biscuit data
|
// Allocate and decrypt the biscuit data
|
||||||
let mut biscuit = Secret::<BISCUIT_PT_LEN>::zero(); // pt buf
|
let mut biscuit = Secret::<BISCUIT_PT_LEN>::zero(); // pt buf
|
||||||
let mut biscuit = (&mut biscuit.secret_mut()[..]).biscuit()?; // slice
|
let mut biscuit = (&mut biscuit.secret_mut()[..]).biscuit()?; // slice
|
||||||
xaead_dec_into(
|
xaead::decrypt(
|
||||||
biscuit.all_bytes_mut(),
|
biscuit.all_bytes_mut(),
|
||||||
bk.get(srv).key.secret(),
|
bk.get(srv).key.secret(),
|
||||||
&ad,
|
&ad,
|
||||||
|
|||||||
@@ -6,10 +6,8 @@ use rosenpass_constant_time::xor_into;
|
|||||||
use rosenpass_util::attempt;
|
use rosenpass_util::attempt;
|
||||||
use static_assertions::const_assert_eq;
|
use static_assertions::const_assert_eq;
|
||||||
use std::os::raw::c_ulonglong;
|
use std::os::raw::c_ulonglong;
|
||||||
use std::ptr::{null as nullptr, null_mut as nullptr_mut};
|
use std::ptr::null as nullptr;
|
||||||
|
|
||||||
pub const XAEAD_TAG_LEN: usize = libsodium::crypto_aead_xchacha20poly1305_ietf_ABYTES as usize;
|
|
||||||
pub const XAEAD_NONCE_LEN: usize = libsodium::crypto_aead_xchacha20poly1305_IETF_NPUBBYTES as usize;
|
|
||||||
pub const NONCE0: [u8; libsodium::crypto_aead_chacha20poly1305_IETF_NPUBBYTES as usize] =
|
pub const NONCE0: [u8; libsodium::crypto_aead_chacha20poly1305_IETF_NPUBBYTES as usize] =
|
||||||
[0u8; libsodium::crypto_aead_chacha20poly1305_IETF_NPUBBYTES as usize];
|
[0u8; libsodium::crypto_aead_chacha20poly1305_IETF_NPUBBYTES as usize];
|
||||||
pub const NOTHING: [u8; 0] = [0u8; 0];
|
pub const NOTHING: [u8; 0] = [0u8; 0];
|
||||||
@@ -31,62 +29,6 @@ macro_rules! sodium_call {
|
|||||||
($name:ident) => { sodium_call!($name, ) };
|
($name:ident) => { sodium_call!($name, ) };
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn xaead_enc_into(
|
|
||||||
ciphertext: &mut [u8],
|
|
||||||
key: &[u8],
|
|
||||||
nonce: &[u8],
|
|
||||||
ad: &[u8],
|
|
||||||
plaintext: &[u8],
|
|
||||||
) -> Result<()> {
|
|
||||||
assert!(ciphertext.len() == plaintext.len() + XAEAD_NONCE_LEN + XAEAD_TAG_LEN);
|
|
||||||
assert!(key.len() == libsodium::crypto_aead_xchacha20poly1305_IETF_KEYBYTES as usize);
|
|
||||||
let (n, ct) = ciphertext.split_at_mut(XAEAD_NONCE_LEN);
|
|
||||||
n.copy_from_slice(nonce);
|
|
||||||
let mut clen: u64 = 0;
|
|
||||||
sodium_call!(
|
|
||||||
crypto_aead_xchacha20poly1305_ietf_encrypt,
|
|
||||||
ct.as_mut_ptr(),
|
|
||||||
&mut clen,
|
|
||||||
plaintext.as_ptr(),
|
|
||||||
plaintext.len() as c_ulonglong,
|
|
||||||
ad.as_ptr(),
|
|
||||||
ad.len() as c_ulonglong,
|
|
||||||
nullptr(), // nsec is not used
|
|
||||||
nonce.as_ptr(),
|
|
||||||
key.as_ptr()
|
|
||||||
)?;
|
|
||||||
assert!(clen as usize == ct.len());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn xaead_dec_into(
|
|
||||||
plaintext: &mut [u8],
|
|
||||||
key: &[u8],
|
|
||||||
ad: &[u8],
|
|
||||||
ciphertext: &[u8],
|
|
||||||
) -> Result<()> {
|
|
||||||
assert!(ciphertext.len() == plaintext.len() + XAEAD_NONCE_LEN + XAEAD_TAG_LEN);
|
|
||||||
assert!(key.len() == libsodium::crypto_aead_xchacha20poly1305_IETF_KEYBYTES as usize);
|
|
||||||
let (n, ct) = ciphertext.split_at(XAEAD_NONCE_LEN);
|
|
||||||
let mut mlen: u64 = 0;
|
|
||||||
sodium_call!(
|
|
||||||
crypto_aead_xchacha20poly1305_ietf_decrypt,
|
|
||||||
plaintext.as_mut_ptr(),
|
|
||||||
&mut mlen as *mut c_ulonglong,
|
|
||||||
nullptr_mut(), // nsec is not used
|
|
||||||
ct.as_ptr(),
|
|
||||||
ct.len() as c_ulonglong,
|
|
||||||
ad.as_ptr(),
|
|
||||||
ad.len() as c_ulonglong,
|
|
||||||
n.as_ptr(),
|
|
||||||
key.as_ptr()
|
|
||||||
)?;
|
|
||||||
assert!(mlen as usize == plaintext.len());
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn blake2b_flexible(out: &mut [u8], key: &[u8], data: &[u8]) -> Result<()> {
|
fn blake2b_flexible(out: &mut [u8], key: &[u8], data: &[u8]) -> Result<()> {
|
||||||
const KEY_MIN: usize = libsodium::crypto_generichash_KEYBYTES_MIN as usize;
|
const KEY_MIN: usize = libsodium::crypto_generichash_KEYBYTES_MIN as usize;
|
||||||
|
|||||||
Reference in New Issue
Block a user