Add chacha module to encrypt ledger files

This commit is contained in:
Stephen Akridge 2018-09-27 10:48:40 -07:00 committed by sakridge
parent abd13ba4ca
commit aa2a3fe201
8 changed files with 148 additions and 3 deletions

View File

@ -34,6 +34,7 @@ name = "solana-drone"
path = "src/bin/drone.rs"
[[bin]]
required-features = ["chacha"]
name = "solana-replicator"
path = "src/bin/replicator.rs"
@ -70,6 +71,7 @@ ipv6 = []
cuda = []
erasure = []
test = []
chacha = []
[dependencies]
atty = "0.2"
@ -131,6 +133,10 @@ name = "signature"
[[bench]]
name = "sigverify"
[[bench]]
required-features = ["chacha"]
name = "chacha"
[workspace]
members = [
".",

29
benches/chacha.rs Normal file
View File

@ -0,0 +1,29 @@
#![feature(test)]
extern crate solana;
extern crate test;
use solana::chacha::chacha_cbc_encrypt_files;
use std::fs::remove_file;
use std::fs::File;
use std::io::Write;
use std::path::Path;
use test::Bencher;
#[bench]
fn bench_chacha_encrypt(bench: &mut Bencher) {
let in_path = Path::new("bench_chacha_encrypt_file_input.txt");
let out_path = Path::new("bench_chacha_encrypt_file_output.txt.enc");
{
let mut in_file = File::create(in_path).unwrap();
for _ in 0..1024 {
in_file.write("123456foobar".as_bytes()).unwrap();
}
}
bench.iter(move || {
chacha_cbc_encrypt_files(in_path, out_path, "thetestkey".to_string()).unwrap();
});
remove_file(in_path).unwrap();
remove_file(out_path).unwrap();
}

View File

@ -16,8 +16,9 @@ fn main() {
let cuda = !env::var("CARGO_FEATURE_CUDA").is_err();
let erasure = !env::var("CARGO_FEATURE_ERASURE").is_err();
let chacha = !env::var("CARGO_FEATURE_CHACHA").is_err();
if cuda || erasure {
if cuda || erasure || chacha {
println!("cargo:rustc-link-search=native=target/perf-libs");
}
if cuda {

View File

@ -20,7 +20,7 @@ _() {
"$@"
}
_ cargo test --features=cuda,erasure
_ cargo test --features=cuda,erasure,chacha
echo --- ci/localnet-sanity.sh
(

View File

@ -15,7 +15,7 @@ mkdir -p target/perf-libs
cd target/perf-libs
(
set -x
curl https://solana-perf.s3.amazonaws.com/v0.9.0/x86_64-unknown-linux-gnu/solana-perf.tgz | tar zxvf -
curl https://solana-perf.s3.amazonaws.com/v0.9.1/x86_64-unknown-linux-gnu/solana-perf.tgz | tar zxvf -
)
if [[ -r /usr/local/cuda/version.txt && -r cuda-version.txt ]]; then

View File

@ -6,6 +6,7 @@ extern crate serde_json;
extern crate solana;
use clap::{App, Arg};
use solana::chacha::chacha_cbc_encrypt_files;
use solana::crdt::Node;
use solana::fullnode::Config;
use solana::logger;
@ -13,6 +14,7 @@ use solana::replicator::Replicator;
use solana::signature::{Keypair, KeypairUtil};
use std::fs::File;
use std::net::{Ipv4Addr, SocketAddr};
use std::path::Path;
use std::process::exit;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc;
@ -21,6 +23,7 @@ use std::time::Duration;
fn main() {
logger::setup();
let matches = App::new("replicator")
.version(crate_version!())
.arg(
@ -102,5 +105,21 @@ fn main() {
println!("Done downloading ledger");
let ledger_path = Path::new(ledger_path.unwrap());
let ledger_data_file = ledger_path.join("data");
let ledger_data_file_encrypted = ledger_path.join("data.enc");
let key = "abc123";
if let Err(e) = chacha_cbc_encrypt_files(
&ledger_data_file,
&ledger_data_file_encrypted,
key.to_string(),
) {
println!("Error while encrypting ledger: {:?}", e);
return;
}
println!("Done encrypting the ledger");
replicator.join();
}

88
src/chacha.rs Normal file
View File

@ -0,0 +1,88 @@
use std::fs::File;
use std::io;
use std::io::Read;
use std::io::Write;
use std::io::{BufReader, BufWriter};
use std::path::Path;
const CHACHA_IVEC_SIZE: usize = 64;
#[link(name = "cpu-crypt")]
extern "C" {
fn chacha20_cbc_encrypt(
input: *const u8,
output: *mut u8,
in_len: usize,
key: *const u8,
ivec: *mut u8,
);
}
pub fn chacha_cbc_encrypt(input: &[u8], output: &mut [u8], key: &[u8], ivec: &mut [u8]) {
unsafe {
chacha20_cbc_encrypt(
input.as_ptr(),
output.as_mut_ptr(),
input.len(),
key.as_ptr(),
ivec.as_mut_ptr(),
);
}
}
pub fn chacha_cbc_encrypt_files(in_path: &Path, out_path: &Path, key: String) -> io::Result<()> {
let mut in_file = BufReader::new(File::open(in_path).expect("Can't open ledger data file"));
let mut out_file =
BufWriter::new(File::create(out_path).expect("Can't open ledger encrypted data file"));
let mut buffer = [0; 4 * 1024];
let mut encrypted_buffer = [0; 4 * 1024];
let mut ivec = [0; CHACHA_IVEC_SIZE];
while let Ok(size) = in_file.read(&mut buffer) {
info!("read {} bytes", size);
if size == 0 {
break;
}
chacha_cbc_encrypt(
&buffer[..size],
&mut encrypted_buffer[..size],
key.as_bytes(),
&mut ivec,
);
if let Err(res) = out_file.write(&encrypted_buffer[..size]) {
println!("Error writing file! {:?}", res);
return Err(res);
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use chacha::chacha_cbc_encrypt_files;
use std::fs::remove_file;
use std::fs::File;
use std::io::Read;
use std::io::Write;
use std::path::Path;
#[test]
fn test_encrypt_file() {
let in_path = Path::new("test_chacha_encrypt_file_input.txt");
let out_path = Path::new("test_chacha_encrypt_file_output.txt.enc");
{
let mut in_file = File::create(in_path).unwrap();
in_file.write("123456foobar".as_bytes()).unwrap();
}
assert!(chacha_cbc_encrypt_files(in_path, out_path, "thetestkey".to_string()).is_ok());
let mut out_file = File::open(out_path).unwrap();
let mut buf = vec![];
let size = out_file.read_to_end(&mut buf).unwrap();
assert_eq!(
buf[..size],
[106, 186, 59, 108, 165, 33, 118, 212, 70, 238, 205, 185]
);
remove_file(in_path).unwrap();
remove_file(out_path).unwrap();
}
}

View File

@ -16,6 +16,8 @@ pub mod broadcast_stage;
pub mod budget;
pub mod budget_instruction;
pub mod budget_transaction;
#[cfg(feature = "chacha")]
pub mod chacha;
pub mod choose_gossip_peer_strategy;
pub mod client;
#[macro_use]