mirror of https://github.com/dswd/vpncloud.git
Removed libsodium completely
This commit is contained in:
parent
ca909d1320
commit
6a3208949e
|
@ -1,3 +0,0 @@
|
|||
[submodule "libsodium"]
|
||||
path = libsodium
|
||||
url = https://github.com/jedisct1/libsodium
|
3
Makefile
3
Makefile
|
@ -3,17 +3,14 @@ default: test build
|
|||
|
||||
.PHONY: build
|
||||
build:
|
||||
git submodule update --init
|
||||
cargo build --release
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
git submodule update --init
|
||||
cargo test
|
||||
|
||||
.PHONY: bench
|
||||
bench:
|
||||
git submodule update --init
|
||||
cargo bench --features bench
|
||||
|
||||
.PHONY: deb
|
||||
|
|
35
build.rs
35
build.rs
|
@ -3,42 +3,7 @@
|
|||
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
||||
|
||||
extern crate cc;
|
||||
extern crate pkg_config;
|
||||
|
||||
use std::process::Command;
|
||||
use std::path::PathBuf;
|
||||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
fn main() {
|
||||
cc::Build::new().file("src/c/tuntap.c").include("src").compile("libtuntap.a");
|
||||
if cfg!(feature = "system-libsodium") {
|
||||
pkg_config::Config::new().atleast_version("1.0.8").probe("libsodium").expect("Libsodium >= 1.0.8 missing");
|
||||
return
|
||||
} else {
|
||||
let target = env::var("TARGET").unwrap();
|
||||
let dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
let libsodium_dir = dir.join("libsodium");
|
||||
let libsodium_target_dir = dir.join("target/sodium-build").join(&target);
|
||||
let libsodium_target_file = libsodium_target_dir.join("libsodium.a");
|
||||
if ! libsodium_target_file.exists() {
|
||||
fs::create_dir_all(&libsodium_target_dir).unwrap();
|
||||
Command::new("make").arg("clean").current_dir(&libsodium_dir).status().unwrap();
|
||||
Command::new("sh").arg("autogen.sh").current_dir(&libsodium_dir).status().unwrap();
|
||||
let mut args = vec!["configure", "--host", &target];
|
||||
if target.starts_with("i686-") {
|
||||
args.extend(vec!["CFLAGS=-m32", "CXXFLAGS=-m32", "LDFLAGS=-m32"]);
|
||||
}
|
||||
if target.ends_with("-musl") {
|
||||
args.extend(vec!["CC=musl-gcc"]);
|
||||
}
|
||||
if target == "arm-unknown-linux-gnueabihf" || target == "armv7-unknown-linux-gnueabihf" {
|
||||
args.extend(vec!["CC=arm-linux-gnueabihf-gcc"]);
|
||||
}
|
||||
Command::new("sh").args(&args).current_dir(&libsodium_dir).status().unwrap();
|
||||
Command::new("make").current_dir(&libsodium_dir).status().unwrap();
|
||||
fs::copy(libsodium_dir.join("src/libsodium/.libs/libsodium.a"), libsodium_target_file).unwrap();
|
||||
}
|
||||
println!("cargo:rustc-link-search={}", libsodium_target_dir.to_str().unwrap());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Subproject commit 675149b9b8b66ff44152553fb3ebf9858128363d
|
154
src/crypto.rs
154
src/crypto.rs
|
@ -2,106 +2,13 @@
|
|||
// Copyright (C) 2015-2017 Dennis Schwerdel
|
||||
// This software is licensed under GPL-3 or newer (see LICENSE.md)
|
||||
|
||||
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 ring::pbkdf2;
|
||||
use ring::rand::*;
|
||||
use ring::digest::*;
|
||||
|
||||
use super::types::Error;
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_chacha20poly1305_ietf_KEYBYTES: usize = 32;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_chacha20poly1305_ietf_NSECBYTES: usize = 0;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_chacha20poly1305_ietf_NPUBBYTES: usize = 12;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_chacha20poly1305_ietf_ABYTES: usize = 16;
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_aes256gcm_KEYBYTES: usize = 32;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_aes256gcm_NSECBYTES: usize = 0;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_aes256gcm_NPUBBYTES: usize = 12;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_aes256gcm_ABYTES: usize = 16;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_aead_aes256gcm_STATEBYTES: usize = 512;
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_pwhash_scryptsalsa208sha256_SALTBYTES: usize = 32;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_pwhash_scryptsalsa208sha256_STRBYTES: usize = 102;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE: usize = 524_288;
|
||||
#[allow(non_upper_case_globals)]
|
||||
const crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE: usize = 16_777_216;
|
||||
|
||||
|
||||
#[link(name="sodium", kind="static")]
|
||||
extern {
|
||||
pub fn sodium_init() -> c_int;
|
||||
pub fn randombytes_buf(buf: *mut u8, size: size_t);
|
||||
pub fn sodium_version_string() -> *const c_char;
|
||||
pub fn crypto_aead_aes256gcm_is_available() -> c_int;
|
||||
pub fn crypto_pwhash_scryptsalsa208sha256(
|
||||
out: *mut u8,
|
||||
outlen: c_ulonglong,
|
||||
passwd: *const u8,
|
||||
passwdlen: c_ulonglong,
|
||||
salt: *const [u8; crypto_pwhash_scryptsalsa208sha256_SALTBYTES],
|
||||
opslimit: c_ulonglong,
|
||||
memlimit: size_t) -> c_int;
|
||||
pub fn crypto_aead_chacha20poly1305_ietf_encrypt(
|
||||
c: *mut u8,
|
||||
clen: *mut c_ulonglong,
|
||||
m: *const u8,
|
||||
mlen: c_ulonglong,
|
||||
ad: *const u8,
|
||||
adlen: c_ulonglong,
|
||||
nsec: *const [u8; crypto_aead_chacha20poly1305_ietf_NSECBYTES],
|
||||
npub: *const [u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES],
|
||||
k: *const [u8; crypto_aead_chacha20poly1305_ietf_KEYBYTES]) -> c_int;
|
||||
pub fn crypto_aead_chacha20poly1305_ietf_decrypt(
|
||||
m: *mut u8,
|
||||
mlen: *mut c_ulonglong,
|
||||
nsec: *mut [u8; crypto_aead_chacha20poly1305_ietf_NSECBYTES],
|
||||
c: *const u8,
|
||||
clen: c_ulonglong,
|
||||
ad: *const u8,
|
||||
adlen: c_ulonglong,
|
||||
npub: *const [u8; crypto_aead_chacha20poly1305_ietf_NPUBBYTES],
|
||||
k: *const [u8; crypto_aead_chacha20poly1305_ietf_KEYBYTES]) -> c_int;
|
||||
pub fn crypto_aead_aes256gcm_beforenm(
|
||||
state: *mut [u8; crypto_aead_aes256gcm_STATEBYTES],
|
||||
k: *const [u8; crypto_aead_aes256gcm_KEYBYTES]) -> c_int;
|
||||
pub fn crypto_aead_aes256gcm_encrypt_afternm(
|
||||
c: *mut u8,
|
||||
clen: *mut c_ulonglong,
|
||||
m: *const u8,
|
||||
mlen: c_ulonglong,
|
||||
ad: *const u8,
|
||||
adlen: c_ulonglong,
|
||||
nsec: *const [u8; crypto_aead_aes256gcm_NSECBYTES],
|
||||
npub: *const [u8; crypto_aead_aes256gcm_NPUBBYTES],
|
||||
state: *const [u8; crypto_aead_aes256gcm_STATEBYTES]) -> c_int;
|
||||
pub fn crypto_aead_aes256gcm_decrypt_afternm(
|
||||
m: *mut u8,
|
||||
mlen: *mut c_ulonglong,
|
||||
nsec: *mut [u8; crypto_aead_aes256gcm_NSECBYTES],
|
||||
c: *const u8,
|
||||
clen: c_ulonglong,
|
||||
ad: *const u8,
|
||||
adlen: c_ulonglong,
|
||||
npub: *const [u8; crypto_aead_aes256gcm_NPUBBYTES],
|
||||
state: *const [u8; crypto_aead_aes256gcm_STATEBYTES]) -> c_int;
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||
pub enum CryptoMethod {
|
||||
|
@ -117,6 +24,7 @@ pub struct CryptoData {
|
|||
nonce: Vec<u8>
|
||||
}
|
||||
|
||||
#[allow(unknown_lints, clippy::large_enum_variant)]
|
||||
pub enum Crypto {
|
||||
None,
|
||||
ChaCha20Poly1305(CryptoData),
|
||||
|
@ -130,27 +38,21 @@ fn inc_nonce(nonce: &mut [u8]) {
|
|||
num = num.wrapping_add(1);
|
||||
nonce[i] = num;
|
||||
if num > 0 {
|
||||
break
|
||||
return
|
||||
}
|
||||
}
|
||||
warn!("Nonce overflowed");
|
||||
}
|
||||
|
||||
|
||||
impl Crypto {
|
||||
#[inline]
|
||||
pub fn init() {
|
||||
CRYPTO_INIT.call_once(|| {
|
||||
if unsafe { sodium_init() } != 0 {
|
||||
fail!("Failed to initialize crypto library");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn sodium_version() -> String {
|
||||
unsafe {
|
||||
CStr::from_ptr(sodium_version_string()).to_string_lossy().to_string()
|
||||
}
|
||||
"0".to_string()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -180,38 +82,30 @@ impl Crypto {
|
|||
pub fn additional_bytes(&self) -> usize {
|
||||
match *self {
|
||||
Crypto::None => 0,
|
||||
Crypto::ChaCha20Poly1305{..} => crypto_aead_chacha20poly1305_ietf_ABYTES,
|
||||
Crypto::AES256GCM{..} => crypto_aead_aes256gcm_ABYTES
|
||||
Crypto::ChaCha20Poly1305(ref data) | Crypto::AES256GCM(ref data) => data.sealing_key.algorithm().tag_len()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_shared_key(method: CryptoMethod, password: &str) -> Self {
|
||||
let salt = b"vpncloudVPNCLOUDvpncl0udVpnCloud";
|
||||
assert_eq!(salt.len(), crypto_pwhash_scryptsalsa208sha256_SALTBYTES);
|
||||
let mut key = [0; crypto_pwhash_scryptsalsa208sha256_STRBYTES];
|
||||
let res = unsafe { crypto_pwhash_scryptsalsa208sha256(
|
||||
key.as_mut_ptr(),
|
||||
key.len() as u64,
|
||||
password.as_bytes().as_ptr(),
|
||||
password.as_bytes().len() as u64,
|
||||
salt.as_ptr() as *const [u8; crypto_pwhash_scryptsalsa208sha256_SALTBYTES],
|
||||
crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE as u64,
|
||||
crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE
|
||||
) };
|
||||
if res != 0 {
|
||||
fail!("Key derivation failed");
|
||||
}
|
||||
let algo = match method {
|
||||
CryptoMethod::ChaCha20 => &CHACHA20_POLY1305,
|
||||
CryptoMethod::AES256 => &AES_256_GCM
|
||||
};
|
||||
let mut key: Vec<u8> = Vec::with_capacity(algo.key_len());
|
||||
for _ in 0..algo.key_len() {
|
||||
key.push(0);
|
||||
}
|
||||
let salt = b"vpncloudVPNCLOUDvpncl0udVpnCloud";
|
||||
pbkdf2::derive(&SHA256, 4096, salt, password.as_bytes(), &mut key);
|
||||
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()) };
|
||||
if SystemRandom::new().fill(&mut nonce).is_err() {
|
||||
fail!("Randomizing nonce failed");
|
||||
}
|
||||
let data = CryptoData { sealing_key, opening_key, nonce };
|
||||
match method {
|
||||
CryptoMethod::ChaCha20 => Crypto::ChaCha20Poly1305(data),
|
||||
|
@ -223,24 +117,24 @@ impl Crypto {
|
|||
match *self {
|
||||
Crypto::None => Ok(buf.len()),
|
||||
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())
|
||||
match open_in_place(&data.opening_key, nonce, header, 0, buf) {
|
||||
Ok(plaintext) => Ok(plaintext.len()),
|
||||
Err(_) => Err(Error::Crypto("Failed to decrypt"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encrypt(&mut self, buf: &mut [u8], mlen: usize, nonce_bytes: &mut [u8], header: &[u8]) -> usize {
|
||||
let tag_len = self.additional_bytes();
|
||||
match *self {
|
||||
Crypto::None => mlen,
|
||||
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(data.nonce.as_ptr(), nonce_bytes.as_mut_ptr(), data.nonce.len());
|
||||
}
|
||||
let new_len = seal_in_place(&data.sealing_key, &data.nonce, header, buf, tag_len).expect("Failed to encrypt");
|
||||
nonce_bytes.clone_from_slice(&data.nonce);
|
||||
new_len
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue