use crate::*;
pub const XSALSA_SEEDBYTES: usize =
libsodium_sys::crypto_box_SEEDBYTES as usize;
pub const XSALSA_PUBLICKEYBYTES: usize =
libsodium_sys::crypto_box_PUBLICKEYBYTES as usize;
pub const XSALSA_SECRETKEYBYTES: usize =
libsodium_sys::crypto_box_SECRETKEYBYTES as usize;
pub const XSALSA_MACBYTES: usize = libsodium_sys::crypto_box_MACBYTES as usize;
pub const XSALSA_NONCEBYTES: usize =
libsodium_sys::crypto_box_NONCEBYTES as usize;
pub const XSALSA_SEALBYTES: usize =
libsodium_sys::crypto_box_SEALBYTES as usize;
pub fn xsalsa_seed_keypair(
pub_key: &mut [u8; libsodium_sys::crypto_box_PUBLICKEYBYTES as usize],
sec_key: &mut [u8; libsodium_sys::crypto_box_SECRETKEYBYTES as usize],
seed: &[u8; libsodium_sys::crypto_box_SEEDBYTES as usize],
) -> Result<()> {
crate::sodium_init();
unsafe {
if libsodium_sys::crypto_box_seed_keypair(
raw_ptr_char!(pub_key),
raw_ptr_char!(sec_key),
raw_ptr_char_immut!(seed),
) == 0_i32
{
return Ok(());
}
Err(Error::other("internal"))
}
}
pub fn xsalsa_keypair(
pub_key: &mut [u8; libsodium_sys::crypto_box_PUBLICKEYBYTES as usize],
sec_key: &mut [u8; libsodium_sys::crypto_box_SECRETKEYBYTES as usize],
) -> Result<()> {
crate::sodium_init();
unsafe {
if libsodium_sys::crypto_box_keypair(
raw_ptr_char!(pub_key),
raw_ptr_char!(sec_key),
) == 0_i32
{
return Ok(());
}
Err(Error::other("internal"))
}
}
pub fn xsalsa_easy(
cipher: &mut [u8],
message: &[u8],
nonce: &[u8; libsodium_sys::crypto_box_NONCEBYTES as usize],
dest_pub_key: &[u8; libsodium_sys::crypto_box_PUBLICKEYBYTES as usize],
src_sec_key: &[u8; libsodium_sys::crypto_box_SECRETKEYBYTES as usize],
) -> Result<()> {
let cipher_len =
message.len() + libsodium_sys::crypto_box_MACBYTES as usize;
if cipher.len() != cipher_len {
return Err(Error::other("bad cipher size"));
}
crate::sodium_init();
#[allow(clippy::uninit_vec)]
unsafe {
if libsodium_sys::crypto_box_easy(
raw_ptr_char!(cipher),
raw_ptr_char_immut!(message),
message.len() as libc::c_ulonglong,
raw_ptr_char_immut!(nonce),
raw_ptr_char_immut!(dest_pub_key),
raw_ptr_char_immut!(src_sec_key),
) == 0_i32
{
return Ok(());
}
Err(Error::other("internal"))
}
}
pub fn xsalsa_open_easy(
message: &mut [u8],
cipher: &[u8],
nonce: &[u8; libsodium_sys::crypto_box_NONCEBYTES as usize],
src_pub_key: &[u8; libsodium_sys::crypto_box_PUBLICKEYBYTES as usize],
dest_sec_key: &[u8; libsodium_sys::crypto_box_SECRETKEYBYTES as usize],
) -> Result<()> {
let msg_len = cipher.len() - libsodium_sys::crypto_box_MACBYTES as usize;
if message.len() != msg_len {
return Err(Error::other("bad message size"));
}
crate::sodium_init();
unsafe {
if libsodium_sys::crypto_box_open_easy(
raw_ptr_char!(message),
raw_ptr_char_immut!(cipher),
cipher.len() as libc::c_ulonglong,
raw_ptr_char_immut!(nonce),
raw_ptr_char_immut!(src_pub_key),
raw_ptr_char_immut!(dest_sec_key),
) == 0_i32
{
return Ok(());
}
Err(Error::other("internal"))
}
}
pub fn xsalsa_seal(
cipher: &mut [u8],
message: &[u8],
dest_pub_key: &[u8; libsodium_sys::crypto_box_PUBLICKEYBYTES as usize],
) -> Result<()> {
let c_len = message.len() + libsodium_sys::crypto_box_SEALBYTES as usize;
if cipher.len() != c_len {
return Err(Error::other("bad cipher size"));
}
crate::sodium_init();
unsafe {
if libsodium_sys::crypto_box_seal(
raw_ptr_char!(cipher),
raw_ptr_char_immut!(message),
message.len() as libc::c_ulonglong,
raw_ptr_char_immut!(dest_pub_key),
) == 0_i32
{
return Ok(());
}
Err(Error::other("internal"))
}
}
pub fn xsalsa_seal_open(
message: &mut [u8],
cipher: &[u8],
pub_key: &[u8; libsodium_sys::crypto_box_PUBLICKEYBYTES as usize],
sec_key: &[u8; libsodium_sys::crypto_box_SECRETKEYBYTES as usize],
) -> Result<()> {
let m_len = cipher.len() - libsodium_sys::crypto_box_SEALBYTES as usize;
if message.len() != m_len {
return Err(Error::other("bad message size"));
}
crate::sodium_init();
unsafe {
if libsodium_sys::crypto_box_seal_open(
raw_ptr_char!(message),
raw_ptr_char_immut!(cipher),
cipher.len() as libc::c_ulonglong,
raw_ptr_char_immut!(pub_key),
raw_ptr_char_immut!(sec_key),
) == 0_i32
{
return Ok(());
}
Err(Error::other("internal"))
}
}
#[cfg(test)]
mod tests {
#[test]
fn test_crypto_box_assert_default_salsa() {
let default_box_primitive = unsafe {
let c =
std::ffi::CStr::from_ptr(libsodium_sys::crypto_box_primitive());
c.to_str().unwrap()
};
assert_eq!("curve25519xsalsa20poly1305", default_box_primitive);
}
}