aescrypt_rs/encryptor/
write.rs1use crate::aliases::HmacSha256;
5use crate::aliases::{Aes256Key, EncryptedSessionBlock48, Iv16, PasswordString, PlainTextBlock16};
6use crate::consts::PBKDF2_MAX_ITER;
7use crate::derive_secure_pbkdf2_key;
8use crate::error::AescryptError;
9use crate::utils::xor_blocks;
10use aes::cipher::BlockEncrypt;
11use aes::{Aes256Enc, Block as AesBlock};
12use hmac::Mac;
13use std::io::Write;
14
15#[inline]
16pub fn write_octets<W: Write>(writer: &mut W, data: &[u8]) -> Result<(), AescryptError> {
17 writer.write_all(data).map_err(AescryptError::Io)
18}
19
20#[inline]
21pub fn write_header<W: Write>(writer: &mut W, version: u8) -> Result<(), AescryptError> {
22 if version < 3 {
23 return Err(AescryptError::UnsupportedVersion(version));
24 }
25 write_octets(writer, &[b'A', b'E', b'S', version, 0x00])
26}
27
28#[inline]
29pub fn write_extensions<W: Write>(
30 writer: &mut W,
31 version: u8,
32 extensions: Option<&[u8]>,
33) -> Result<(), AescryptError> {
34 if version < 3 {
35 return Err(AescryptError::UnsupportedVersion(version));
36 }
37 let data = extensions.unwrap_or(&[0x00, 0x00]);
38 write_octets(writer, data)
39}
40
41#[inline]
42pub fn write_iterations<W: Write>(
43 writer: &mut W,
44 iterations: u32,
45 version: u8,
46) -> Result<(), AescryptError> {
47 if version < 3 {
48 return Err(AescryptError::UnsupportedVersion(version));
49 }
50 if iterations == 0 || iterations > PBKDF2_MAX_ITER {
51 return Err(AescryptError::Header("invalid KDF iterations".into()));
52 }
53 write_octets(writer, &iterations.to_be_bytes())
54}
55
56#[inline]
57pub fn write_public_iv<W: Write>(writer: &mut W, iv: &Iv16) -> Result<(), AescryptError> {
58 write_octets(writer, iv.expose_secret())
59}
60
61#[inline]
62pub fn derive_setup_key(
63 password: &PasswordString,
64 public_iv: &Iv16,
65 iterations: u32,
66 out_key: &mut Aes256Key,
67) -> Result<(), AescryptError> {
68 derive_secure_pbkdf2_key(password, public_iv, iterations, out_key)
69}
70
71#[inline]
72pub fn encrypt_session_block(
73 cipher: &Aes256Enc,
74 session_iv: &Iv16,
75 session_key: &Aes256Key,
76 public_iv: &Iv16,
77 enc_block: &mut EncryptedSessionBlock48,
78 hmac: &mut HmacSha256,
79) -> Result<(), AescryptError> {
80 let mut prev = *public_iv.expose_secret();
81 let mut block = PlainTextBlock16::new([0u8; 16]);
82
83 xor_blocks(session_iv.expose_secret(), &prev, block.expose_secret_mut());
85 let mut aes_block = AesBlock::from(*block.expose_secret());
86 cipher.encrypt_block(&mut aes_block);
87 enc_block.expose_secret_mut()[0..16].copy_from_slice(aes_block.as_ref());
88 hmac.update(&enc_block.expose_secret()[0..16]);
89 prev.copy_from_slice(&enc_block.expose_secret()[0..16]);
90
91 xor_blocks(
93 &session_key.expose_secret()[0..16],
94 &prev,
95 block.expose_secret_mut(),
96 );
97 aes_block = AesBlock::from(*block.expose_secret());
98 cipher.encrypt_block(&mut aes_block);
99 enc_block.expose_secret_mut()[16..32].copy_from_slice(aes_block.as_ref());
100 hmac.update(&enc_block.expose_secret()[16..32]);
101 prev.copy_from_slice(&enc_block.expose_secret()[16..32]);
102
103 xor_blocks(
105 &session_key.expose_secret()[16..32],
106 &prev,
107 block.expose_secret_mut(),
108 );
109 aes_block = AesBlock::from(*block.expose_secret());
110 cipher.encrypt_block(&mut aes_block);
111 enc_block.expose_secret_mut()[32..48].copy_from_slice(aes_block.as_ref());
112 hmac.update(&enc_block.expose_secret()[32..48]);
113
114 Ok(())
115}
116
117#[inline]
118pub fn write_hmac<W: Write>(writer: &mut W, hmac: HmacSha256) -> Result<(), AescryptError> {
119 write_octets(writer, hmac.finalize().into_bytes().as_slice())
120}