mirror of https://github.com/dswd/vpncloud.git
Ring instead of libsodium
This commit is contained in:
parent
5d479d6d54
commit
ca909d1320
|
@ -6,16 +6,6 @@ dependencies = [
|
|||
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aligned_alloc"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.4.10"
|
||||
|
@ -574,6 +564,17 @@ dependencies = [
|
|||
"futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
|
@ -938,6 +939,11 @@ dependencies = [
|
|||
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "1.0.2"
|
||||
|
@ -957,7 +963,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
name = "vpncloud"
|
||||
version = "0.8.2"
|
||||
dependencies = [
|
||||
"aligned_alloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cc 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"daemonize 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -969,6 +974,7 @@ dependencies = [
|
|||
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.84 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1052,7 +1058,6 @@ dependencies = [
|
|||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
|
||||
"checksum aligned_alloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9dcebfb002ccde769c15bc841d0d5548a90e80fcd2ffed5131339e8074746f0a"
|
||||
"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
|
||||
"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
|
||||
"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
|
||||
|
@ -1118,6 +1123,7 @@ dependencies = [
|
|||
"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7"
|
||||
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
|
||||
"checksum relay 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1576e382688d7e9deecea24417e350d3062d97e32e45d70b1cde65994ff1489a"
|
||||
"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
|
||||
"checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
|
||||
|
@ -1158,6 +1164,7 @@ dependencies = [
|
|||
"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
|
||||
"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f"
|
||||
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
|
||||
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
||||
|
|
|
@ -19,7 +19,6 @@ serde_yaml = "0.8"
|
|||
log = { version = "0.4", features = ["std"] }
|
||||
signal = "0.6"
|
||||
libc = "0.2"
|
||||
aligned_alloc = "0.1"
|
||||
rand = "0.6"
|
||||
fnv = "1"
|
||||
net2 = "0.2"
|
||||
|
@ -28,6 +27,7 @@ yaml-rust = "0.4"
|
|||
igd = "0.7"
|
||||
siphasher = "0.3"
|
||||
daemonize = "0.3"
|
||||
ring = "0.13"
|
||||
|
||||
[build-dependencies]
|
||||
cc = "^1"
|
||||
|
|
175
src/crypto.rs
175
src/crypto.rs
|
@ -5,11 +5,11 @@
|
|||
use std::ptr;
|
||||
use std::ffi::CStr;
|
||||
use std::sync::{Once, ONCE_INIT};
|
||||
use ring::aead::*;
|
||||
|
||||
static CRYPTO_INIT: Once = ONCE_INIT;
|
||||
|
||||
use libc::{size_t, c_char, c_ulonglong, c_int};
|
||||
use aligned_alloc::{aligned_alloc, aligned_free};
|
||||
|
||||
use super::types::Error;
|
||||
|
||||
|
@ -42,22 +42,6 @@ const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: usize = 524_288;
|
|||
#[allow(non_upper_case_globals)]
|
||||
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: usize = 16_777_216;
|
||||
|
||||
pub struct Aes256State(*mut [u8; crypto_aead_aes256gcm_STATEBYTES]);
|
||||
|
||||
impl Aes256State {
|
||||
fn new() -> Aes256State {
|
||||
let ptr = aligned_alloc(crypto_aead_aes256gcm_STATEBYTES, 16)
|
||||
as *mut [u8; crypto_aead_aes256gcm_STATEBYTES];
|
||||
Aes256State(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Aes256State {
|
||||
fn drop(&mut self) {
|
||||
unsafe { aligned_free(self.0 as *mut ()) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[link(name="sodium", kind="static")]
|
||||
extern {
|
||||
|
@ -127,23 +111,24 @@ pub enum CryptoMethod {
|
|||
AES256
|
||||
}
|
||||
|
||||
pub enum Crypto {
|
||||
None,
|
||||
ChaCha20Poly1305{
|
||||
key: [u8; crypto_aead_chacha20poly1305_ietf_KEYBYTES],
|
||||
nonce: [u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES]
|
||||
},
|
||||
AES256GCM{
|
||||
state: Aes256State,
|
||||
nonce: [u8; crypto_aead_aes256gcm_NPUBBYTES]
|
||||
}
|
||||
pub struct CryptoData {
|
||||
sealing_key: SealingKey,
|
||||
opening_key: OpeningKey,
|
||||
nonce: Vec<u8>
|
||||
}
|
||||
|
||||
fn inc_nonce_12(nonce: &mut [u8; 12]) {
|
||||
for i in 0..12 {
|
||||
let mut num = nonce[11-i];
|
||||
pub enum Crypto {
|
||||
None,
|
||||
ChaCha20Poly1305(CryptoData),
|
||||
AES256GCM(CryptoData)
|
||||
}
|
||||
|
||||
fn inc_nonce(nonce: &mut [u8]) {
|
||||
let l = nonce.len();
|
||||
for i in (0..l).rev() {
|
||||
let mut num = nonce[i];
|
||||
num = num.wrapping_add(1);
|
||||
nonce[11-i] = num;
|
||||
nonce[i] = num;
|
||||
if num > 0 {
|
||||
break
|
||||
}
|
||||
|
@ -170,9 +155,7 @@ impl Crypto {
|
|||
|
||||
#[inline]
|
||||
pub fn aes256_available() -> bool {
|
||||
unsafe {
|
||||
crypto_aead_aes256gcm_is_available() == 1
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -188,7 +171,7 @@ impl Crypto {
|
|||
pub fn nonce_bytes(&self) -> usize {
|
||||
match *self {
|
||||
Crypto::None => 0,
|
||||
Crypto::ChaCha20Poly1305{ref nonce, ..} | Crypto::AES256GCM{ref nonce, ..} => nonce.len(),
|
||||
Crypto::ChaCha20Poly1305(ref data) | Crypto::AES256GCM(ref data) => data.sealing_key.algorithm().nonce_len()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,69 +201,30 @@ impl Crypto {
|
|||
if res != 0 {
|
||||
fail!("Key derivation failed");
|
||||
}
|
||||
let algo = match method {
|
||||
CryptoMethod::ChaCha20 => &CHACHA20_POLY1305,
|
||||
CryptoMethod::AES256 => &AES_256_GCM
|
||||
};
|
||||
let sealing_key = SealingKey::new(algo, &key[..algo.key_len()]).expect("Failed to create key");
|
||||
let opening_key = OpeningKey::new(algo, &key[..algo.key_len()]).expect("Failed to create key");
|
||||
let mut nonce: Vec<u8> = Vec::with_capacity(algo.nonce_len());
|
||||
for _ in 0..algo.nonce_len() {
|
||||
nonce.push(0);
|
||||
}
|
||||
unsafe { randombytes_buf(nonce.as_mut_ptr(), nonce.len()) };
|
||||
let data = CryptoData { sealing_key, opening_key, nonce };
|
||||
match method {
|
||||
CryptoMethod::ChaCha20 => {
|
||||
let mut crypto_key = [0; crypto_aead_chacha20poly1305_ietf_KEYBYTES];
|
||||
crypto_key.clone_from_slice(&key[..crypto_aead_chacha20poly1305_ietf_KEYBYTES]);
|
||||
let mut nonce = [0u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES];
|
||||
unsafe { randombytes_buf(nonce.as_mut_ptr(), nonce.len()) };
|
||||
Crypto::ChaCha20Poly1305{key: crypto_key, nonce}
|
||||
},
|
||||
CryptoMethod::AES256 => {
|
||||
if ! Crypto::aes256_available() {
|
||||
fail!("AES256 is not supported by this processor, use ChaCha20 instead");
|
||||
}
|
||||
let mut nonce = [0u8; crypto_aead_aes256gcm_NPUBBYTES];
|
||||
unsafe { randombytes_buf(nonce.as_mut_ptr(), nonce.len()) };
|
||||
let state = Aes256State::new();
|
||||
let res = unsafe { crypto_aead_aes256gcm_beforenm(
|
||||
state.0,
|
||||
key[..crypto_aead_aes256gcm_KEYBYTES].as_ptr() as *const [u8; crypto_aead_aes256gcm_KEYBYTES]
|
||||
) };
|
||||
assert_eq!(res, 0);
|
||||
Crypto::AES256GCM{state, nonce}
|
||||
}
|
||||
CryptoMethod::ChaCha20 => Crypto::ChaCha20Poly1305(data),
|
||||
CryptoMethod::AES256 => Crypto::AES256GCM(data)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decrypt(&self, buf: &mut [u8], nonce: &[u8], header: &[u8]) -> Result<usize, Error> {
|
||||
match *self {
|
||||
Crypto::None => Ok(buf.len()),
|
||||
Crypto::ChaCha20Poly1305{ref key, ..} => {
|
||||
let mut mlen: u64 = buf.len() as u64;
|
||||
let res = unsafe { crypto_aead_chacha20poly1305_ietf_decrypt(
|
||||
buf.as_mut_ptr(), // Base pointer to buffer
|
||||
&mut mlen, // Mutable size of buffer (will be set to used size)
|
||||
ptr::null_mut::<[u8; 0]>(), // Mutable base pointer to secret nonce (always NULL)
|
||||
buf.as_ptr(), // Base pointer to message
|
||||
buf.len() as u64, // Size of message
|
||||
header.as_ptr(), // Base pointer to additional data
|
||||
header.len() as u64, // Size of additional data
|
||||
nonce.as_ptr() as *const [u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES], // Base pointer to public nonce
|
||||
key.as_ptr() as *const [u8; crypto_aead_chacha20poly1305_ietf_KEYBYTES] // Base pointer to key
|
||||
) };
|
||||
match res {
|
||||
0 => Ok(mlen as usize),
|
||||
_ => Err(Error::Crypto("Failed to decrypt"))
|
||||
}
|
||||
},
|
||||
Crypto::AES256GCM{ref state, ..} => {
|
||||
let mut mlen: u64 = buf.len() as u64;
|
||||
let res = unsafe { crypto_aead_aes256gcm_decrypt_afternm(
|
||||
buf.as_mut_ptr(), // Base pointer to buffer
|
||||
&mut mlen, // Mutable size of buffer (will be set to used size)
|
||||
ptr::null_mut::<[u8; 0]>(), // Mutable base pointer to secret nonce (always NULL)
|
||||
buf.as_ptr(), // Base pointer to message
|
||||
buf.len() as u64, // Size of message
|
||||
header.as_ptr(), // Base pointer to additional data
|
||||
header.len() as u64, // Size of additional data
|
||||
nonce.as_ptr() as *const [u8; crypto_aead_aes256gcm_NPUBBYTES], // Base pointer to public nonce
|
||||
state.0 // Base pointer to state
|
||||
) };
|
||||
match res {
|
||||
0 => Ok(mlen as usize),
|
||||
_ => Err(Error::Crypto("Failed to decrypt"))
|
||||
}
|
||||
Crypto::ChaCha20Poly1305(ref data) | Crypto::AES256GCM(ref data) => {
|
||||
let plaintext = open_in_place(&data.opening_key, nonce, header, 0, buf).expect("error");
|
||||
Ok(plaintext.len())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -288,49 +232,16 @@ impl Crypto {
|
|||
pub fn encrypt(&mut self, buf: &mut [u8], mlen: usize, nonce_bytes: &mut [u8], header: &[u8]) -> usize {
|
||||
match *self {
|
||||
Crypto::None => mlen,
|
||||
Crypto::ChaCha20Poly1305{ref key, ref mut nonce} => {
|
||||
inc_nonce_12(nonce);
|
||||
let mut clen: u64 = buf.len() as u64;
|
||||
assert_eq!(nonce_bytes.len(), nonce.len());
|
||||
assert!(clen as usize >= mlen + crypto_aead_chacha20poly1305_ietf_ABYTES);
|
||||
let res = unsafe { crypto_aead_chacha20poly1305_ietf_encrypt(
|
||||
buf.as_mut_ptr(), // Base pointer to buffer
|
||||
&mut clen, // Mutable size of buffer (will be set to used size)
|
||||
buf.as_ptr(), // Base pointer to message
|
||||
mlen as u64, // Size of message
|
||||
header.as_ptr(), // Base pointer to additional data
|
||||
header.len() as u64, // Size of additional data
|
||||
ptr::null::<[u8; 0]>(), // Base pointer to secret nonce (always NULL)
|
||||
nonce.as_ptr() as *const [u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES], // Base pointer to public nonce
|
||||
key.as_ptr() as *const [u8; crypto_aead_chacha20poly1305_ietf_KEYBYTES] // Base pointer to key
|
||||
) };
|
||||
assert_eq!(res, 0);
|
||||
Crypto::ChaCha20Poly1305(ref mut data) | Crypto::AES256GCM(ref mut data) => {
|
||||
inc_nonce(&mut data.nonce);
|
||||
let tag_len = data.sealing_key.algorithm().tag_len();
|
||||
assert!(buf.len() - mlen >= tag_len);
|
||||
let buf = &mut buf[.. mlen + tag_len];
|
||||
let new_len = seal_in_place(&data.sealing_key, &data.nonce, header, buf, tag_len).expect("error");
|
||||
unsafe {
|
||||
ptr::copy_nonoverlapping(nonce.as_ptr(), nonce_bytes.as_mut_ptr(), nonce.len());
|
||||
ptr::copy_nonoverlapping(data.nonce.as_ptr(), nonce_bytes.as_mut_ptr(), data.nonce.len());
|
||||
}
|
||||
clen as usize
|
||||
},
|
||||
Crypto::AES256GCM{ref state, ref mut nonce} => {
|
||||
inc_nonce_12(nonce);
|
||||
let mut clen: u64 = buf.len() as u64;
|
||||
assert_eq!(nonce_bytes.len(), nonce.len());
|
||||
assert!(clen as usize >= mlen + crypto_aead_aes256gcm_ABYTES);
|
||||
let res = unsafe { crypto_aead_aes256gcm_encrypt_afternm(
|
||||
buf.as_mut_ptr(), // Base pointer to buffer
|
||||
&mut clen, // Mutable size of buffer (will be set to used size)
|
||||
buf.as_ptr(), // Base pointer to message
|
||||
mlen as u64, // Size of message
|
||||
header.as_ptr(), // Base pointer to additional data
|
||||
header.len() as u64, // Size of additional data
|
||||
ptr::null::<[u8; 0]>(), // Base pointer to secret nonce (always NULL)
|
||||
nonce.as_ptr() as *const [u8; crypto_aead_aes256gcm_NPUBBYTES], // Base pointer to public nonce
|
||||
state.0 // Base pointer to state
|
||||
) };
|
||||
assert_eq!(res, 0);
|
||||
unsafe {
|
||||
ptr::copy_nonoverlapping(nonce.as_ptr(), nonce_bytes.as_mut_ptr(), nonce.len());
|
||||
}
|
||||
clen as usize
|
||||
new_len
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ extern crate serde;
|
|||
extern crate serde_yaml;
|
||||
extern crate signal;
|
||||
extern crate libc;
|
||||
extern crate aligned_alloc;
|
||||
extern crate rand;
|
||||
extern crate fnv;
|
||||
extern crate net2;
|
||||
|
@ -21,6 +20,7 @@ extern crate yaml_rust;
|
|||
extern crate igd;
|
||||
extern crate siphasher;
|
||||
extern crate daemonize;
|
||||
extern crate ring;
|
||||
#[cfg(feature = "bench")] extern crate test;
|
||||
|
||||
#[macro_use] pub mod util;
|
||||
|
|
Loading…
Reference in New Issue