ethsign_crypto/
aes.rs

1//! AES symmetric encryption
2
3use aes::{
4    cipher::{generic_array::GenericArray, KeyIvInit, StreamCipher},
5    Aes128,
6};
7use std::fmt;
8
9/// Error type for the AES symmetric encryption
10#[derive(Debug)]
11pub enum SymmError {
12    InvalidKey,
13    InvalidNonce,
14    SourceDestinationMismatch,
15}
16
17impl fmt::Display for SymmError {
18    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19        match self {
20            SymmError::InvalidKey => f.write_str("Key must be 16 bytes long"),
21            SymmError::InvalidNonce => f.write_str("Nonce must be 16 bytes long"),
22            SymmError::SourceDestinationMismatch => f.write_str("Source and destination must have equal length"),
23        }
24    }
25}
26
27/// Encrypt a message (CTR mode).
28///
29/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
30/// An error is returned if the input lengths are invalid.
31pub fn encrypt_128_ctr(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) -> Result<(), SymmError> {
32    if k.len() != 16 {
33        return Err(SymmError::InvalidKey);
34    }
35    if iv.len() != 16 {
36        return Err(SymmError::InvalidNonce);
37    }
38    if plain.len() != dest.len() {
39        return Err(SymmError::SourceDestinationMismatch);
40    }
41
42    let key = GenericArray::from_slice(k);
43    let nonce = GenericArray::from_slice(iv);
44
45    dest.copy_from_slice(plain);
46
47    let mut cipher_ctr = ctr::Ctr128BE::<Aes128>::new(&key, &nonce);
48    cipher_ctr.apply_keystream(dest);
49
50    Ok(())
51}
52
53/// Decrypt a message (CTR mode).
54///
55/// Key (`k`) length and initialisation vector (`iv`) length have to be 16 bytes each.
56/// An error is returned if the input lengths are invalid.
57pub fn decrypt_128_ctr(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<(), SymmError> {
58    // This is symmetrical encryption, so those are equivalent operations
59    encrypt_128_ctr(k, iv, encrypted, dest)
60}