1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
pub mod crypto;
pub mod ctrl;
pub mod file;

use self::crypto::*;
use self::ctrl::*;
use self::file::*;
use rayon::prelude::*;

const TAG: [u8; TAG_LEN as usize] = [0u8; TAG_LEN as usize];

pub fn encrypt(key: &Key, ctrl: &CipherCtrl) -> String {
    let cryption = Cryption::new(key);
    let hmac = Hmac::new(key);
    let fr = FileReader::new(ctrl);
    let fw = FileWriter::new(ctrl);

    let footprint = (0..ctrl.chunk_num)
        .into_par_iter()
        .map(|i| {
            let chunk = fr.get_chunk(i).unwrap();
            let mut buf = chunk.mmap.to_vec();
            buf.extend_from_slice(&TAG);
            (i, buf)
        })
        .map(|(i, mut buf)| {
            cryption.encrypt(&mut buf, &Nonce::from(i));
            (i, buf)
        })
        .map(|(i, buf)| {
            let mut mmap_mut = fw.get_chunk_mut(i).unwrap().mmap_mut;
            mmap_mut.copy_from_slice(&buf);
            mmap_mut.flush().unwrap();
            Vec::from(&buf[buf.len() - TAG_LEN..])
        })
        .reduce_with(|mut acc, x| {
            acc.extend(x);
            acc
        })
        .unwrap();
    let data = Header::new(ctrl.old_meta.size as u64, ctrl.new_meta.chunk_size as u64, hmac.sign(&footprint));
    let mut header = fw.header();
    header.copy_from_slice(&data.data());
    header.flush().unwrap();

    ctrl.new_meta.path.clone()
}

pub fn decrypt(key: &Key, ctrl: &CipherCtrl) -> String {
    let cryption = Cryption::new(key);
    let hmac = Hmac::new(key);
    let fr = FileReader::new(ctrl);
    let fw = FileWriter::new(ctrl);

    let header = fr.header();

    let footprint = (0..ctrl.chunk_num)
        .into_par_iter()
        .map(|i| {
            let chunk = fr.get_chunk(i).unwrap();
            let buf = chunk.mmap.to_vec();
            (i, buf)
        })
        .map(|(i, mut buf)| {
            cryption.decrypt(&mut buf, &Nonce::from(i));
            (i, buf)
        })
        .map(|(i, buf)| {
            let mut mmap_mut = fw.get_chunk_mut(i).unwrap().mmap_mut;
            mmap_mut.copy_from_slice(&buf[..buf.len() - TAG_LEN]);
            mmap_mut.flush().unwrap();

            Vec::from(&buf[buf.len() - TAG_LEN..])
        })
        .reduce_with(|mut acc, x| {
            acc.extend(x);
            acc
        })
        .unwrap();

    let header_data = Header::from_slice(header.as_ref());
    if !hmac.verify(&footprint, &header_data.signature) {
        panic!("Footprint not match.");
    }

    ctrl.new_meta.path.clone()
}