volaris_crypto/primitives.rs
1//! This module contains all cryptographic primitives used by `volaris-crypto`
2use crate::protected::Protected;
3use rand::{prelude::ThreadRng, RngCore};
4
5/// This is the streaming block size
6///
7/// NOTE: Stream mode can be used to encrypt files less than this size, provided the implementation
8/// is correct
9pub const BLOCK_SIZE: usize = 1_048_576; // 1024*1024 bytes
10
11/// This is the length of the salt used for password hashing
12pub const SALT_LEN: usize = 16; // bytes
13
14pub const MASTER_KEY_LEN: usize = 32;
15pub const ENCRYPTED_MASTER_KEY_LEN: usize = 48;
16pub const ALGORITHMS_LEN: usize = 3;
17
18/// This is an `enum` containing all AEADs supported by `volaris-crypto`
19#[derive(Copy, Clone, PartialEq, Eq)]
20pub enum Algorithm {
21 Aes256Gcm,
22 XChaCha20Poly1305,
23 DeoxysII256,
24}
25
26/// This is an array containing all AEADs supported by `volaris-crypto`.
27///
28/// It can be used by and end-user application to show a list of AEADs that they may use
29pub static ALGORITHMS: [Algorithm; ALGORITHMS_LEN] = [
30 Algorithm::XChaCha20Poly1305,
31 Algorithm::Aes256Gcm,
32 Algorithm::DeoxysII256,
33];
34
35impl std::fmt::Display for Algorithm {
36 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
37 match self {
38 Algorithm::Aes256Gcm => write!(f, "AES-256-GCM"),
39 Algorithm::XChaCha20Poly1305 => write!(f, "XChaCha20-Poly1305"),
40 Algorithm::DeoxysII256 => write!(f, "Deoxys-II-256"),
41 }
42 }
43}
44
45/// This defines the possible modes used for encrypting/decrypting
46#[derive(PartialEq, Eq)]
47pub enum Mode {
48 MemoryMode,
49 StreamMode,
50}
51
52impl std::fmt::Display for Mode {
53 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
54 match self {
55 Mode::MemoryMode => write!(f, "Memory Mode"),
56 Mode::StreamMode => write!(f, "Stream Mode"),
57 }
58 }
59}
60
61/// This can be used to generate a nonce for encryption
62/// It requires both the algorithm and the mode, so it can correctly determine the nonce length
63/// This nonce can be passed directly to `EncryptionStreams::initialize()`
64///
65/// # Examples
66///
67/// ```rust
68/// # use Volaris_corecrypto::primitives::*;
69/// let nonce = gen_nonce(&Algorithm::XChaCha20Poly1305, &Mode::StreamMode);
70/// ```
71///
72#[must_use]
73pub fn gen_nonce(algorithm: &Algorithm, mode: &Mode) -> Vec<u8> {
74 let nonce_len = get_nonce_len(algorithm, mode);
75 let mut nonce = vec![0u8; nonce_len];
76 ThreadRng::default().fill_bytes(&mut nonce);
77 nonce
78}
79
80/// This function calculates the length of the nonce, depending on the data provided
81///
82/// Stream mode nonces are 4 bytes less than their "memory" mode counterparts, due to `aead::StreamLE31`
83///
84/// `StreamLE31` contains a 31-bit little endian counter, and a 1-bit "last block" flag, stored as the last 4 bytes of the nonce, this is done to prevent nonce-reuse
85#[must_use]
86pub fn get_nonce_len(algorithm: &Algorithm, mode: &Mode) -> usize {
87 let mut nonce_len = match algorithm {
88 Algorithm::Aes256Gcm => 12,
89 Algorithm::XChaCha20Poly1305 => 24,
90 Algorithm::DeoxysII256 => 15,
91 };
92
93 if mode == &Mode::StreamMode {
94 nonce_len -= 4;
95 }
96
97 nonce_len
98}
99
100/// Generates a new protected master key of the specified `MASTER_KEY_LEN`.
101///
102/// This can be used to generate a master key for encryption.
103/// It uses `ThreadRng` to securely generate completely random bytes, with extra protection
104/// from some side-channel attacks
105///
106/// # Examples
107///
108/// ```rust
109/// # use Volaris_corecrypto::primitives::*;
110/// let master_key = gen_master_key();
111/// ```
112///
113#[must_use]
114pub fn gen_master_key() -> Protected<[u8; MASTER_KEY_LEN]> {
115 let mut master_key = [0u8; MASTER_KEY_LEN];
116 ThreadRng::default().fill_bytes(&mut master_key);
117 Protected::new(master_key)
118}
119
120/// Generates a salt, of the specified `SALT_LEN`
121///
122/// This salt can be directly passed to `argon2id_hash()` or `balloon_hash()`
123///
124/// # Examples
125///
126/// ```rust
127/// # use Volaris_corecrypto::primitives::*;
128/// let salt = gen_salt();
129/// ```
130///
131#[must_use]
132pub fn gen_salt() -> [u8; SALT_LEN] {
133 let mut salt = [0u8; SALT_LEN];
134 ThreadRng::default().fill_bytes(&mut salt);
135 salt
136}