Add chacha module to encrypt ledger files
This commit is contained in:
		
				
					committed by
					
						
						sakridge
					
				
			
			
				
	
			
			
			
						parent
						
							abd13ba4ca
						
					
				
				
					commit
					aa2a3fe201
				
			@@ -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
									
								
							
							
						
						
									
										29
									
								
								benches/chacha.rs
									
									
									
									
									
										Normal 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();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								build.rs
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								build.rs
									
									
									
									
									
								
							@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ _() {
 | 
			
		||||
  "$@"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_ cargo test --features=cuda,erasure
 | 
			
		||||
_ cargo test --features=cuda,erasure,chacha
 | 
			
		||||
 | 
			
		||||
echo --- ci/localnet-sanity.sh
 | 
			
		||||
(
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
									
								
							
							
						
						
									
										88
									
								
								src/chacha.rs
									
									
									
									
									
										Normal 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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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]
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user