Skip to content

Instantly share code, notes, and snippets.

@lain-dono
Created November 2, 2018 15:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lain-dono/11079895ad25d41cc53fe0d371bc948a to your computer and use it in GitHub Desktop.
Save lain-dono/11079895ad25d41cc53fe0d371bc948a to your computer and use it in GitHub Desktop.
Minimal binding to libsodium
use std::os::raw::{c_int, c_uchar, c_ulonglong};
use super::{HMAC, KEY, NONCE, XNONCE};
pub const KEY: usize = 32;
pub const HMAC: usize = 16;
pub const NONCE: usize = 12;
pub const XNONCE: usize = 24;
#[link(name = "sodium")]
extern "C" {
fn crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
c: *mut c_uchar,
mac: *mut c_uchar,
maclen_p: *mut c_ulonglong,
m: *const c_uchar,
mlen: c_ulonglong,
ad: *const c_uchar,
adlen: c_ulonglong,
nsec: *const c_uchar,
npub: *const c_uchar,
k: *const c_uchar
) -> c_int;
fn crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
m: *mut c_uchar,
nsec: *mut c_uchar,
c: *const c_uchar,
clen: c_ulonglong,
mac: *const c_uchar,
ad: *const c_uchar,
adlen: c_ulonglong,
npub: *const c_uchar,
k: *const c_uchar
) -> c_int;
fn crypto_aead_chacha20poly1305_ietf_encrypt_detached(
c: *mut c_uchar,
mac: *mut c_uchar,
maclen_p: *mut c_ulonglong,
m: *const c_uchar,
mlen: c_ulonglong,
ad: *const c_uchar,
adlen: c_ulonglong,
nsec: *const c_uchar,
npub: *const c_uchar,
k: *const c_uchar
) -> c_int;
fn crypto_aead_chacha20poly1305_ietf_decrypt_detached(
m: *mut c_uchar,
nsec: *mut c_uchar,
c: *const c_uchar,
clen: c_ulonglong,
mac: *const c_uchar,
ad: *const c_uchar,
adlen: c_ulonglong,
npub: *const c_uchar,
k: *const c_uchar
) -> c_int;
}
pub fn open(c: &mut [u8], ad: Option<&[u8]>, t: &[u8; HMAC], n: &[u8; NONCE], k: &[u8; KEY]) -> Result<(), ()> {
let (ad_p, ad_len) = ad.map(|ad| (ad.as_ptr(), ad.len() as c_ulonglong)).unwrap_or((0 as *const _, 0));
let ret = unsafe {
crypto_aead_chacha20poly1305_ietf_decrypt_detached(
c.as_mut_ptr(),
0 as *mut _,
c.as_ptr(),
c.len() as c_ulonglong,
t.as_ptr(),
ad_p,
ad_len,
n.as_ptr(),
k.as_ptr()
)
};
if ret == 0 {
Ok(())
} else {
Err(())
}
}
pub fn seal(m: &mut [u8], ad: Option<&[u8]>, n: &[u8; NONCE], k: &[u8; KEY]) -> [u8; HMAC] {
let (ad_p, ad_len) = ad.map(|ad| (ad.as_ptr(), ad.len() as c_ulonglong)).unwrap_or((0 as *const _, 0));
let mut tag = [0u8; HMAC];
let mut maclen = HMAC as c_ulonglong;
unsafe {
crypto_aead_chacha20poly1305_ietf_encrypt_detached(
m.as_mut_ptr(),
tag.as_mut_ptr(),
&mut maclen,
m.as_ptr(),
m.len() as c_ulonglong,
ad_p,
ad_len,
0 as *mut _,
n.as_ptr(),
k.as_ptr()
);
}
tag
}
pub fn xopen(c: &mut [u8], ad: &[u8], t: &[u8; HMAC], n: &[u8; XNONCE], k: &[u8; KEY]) -> Result<(), ()> {
let (ad_p, ad_len) = (ad.as_ptr(), ad.len() as c_ulonglong);
let ret = unsafe {
crypto_aead_xchacha20poly1305_ietf_decrypt_detached(
c.as_mut_ptr(),
0 as *mut _,
c.as_ptr(),
c.len() as c_ulonglong,
t.as_ptr(),
ad_p,
ad_len,
n.as_ptr(),
k.as_ptr()
)
};
if ret == 0 {
Ok(())
} else {
Err(())
}
}
pub fn xseal(m: &mut [u8], ad: &[u8], n: &[u8; XNONCE], k: &[u8; KEY]) -> [u8; HMAC] {
let (ad_p, ad_len) = (ad.as_ptr(), ad.len() as c_ulonglong);
let mut tag = [0u8; HMAC];
let mut maclen = HMAC as c_ulonglong;
unsafe {
crypto_aead_xchacha20poly1305_ietf_encrypt_detached(
m.as_mut_ptr(),
tag.as_mut_ptr(),
&mut maclen,
m.as_ptr(),
m.len() as c_ulonglong,
ad_p,
ad_len,
0 as *mut _,
n.as_ptr(),
k.as_ptr()
);
}
tag
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment