Skip to main content

lb_rs/model/
symkey.rs

1use crate::model::crypto::*;
2use aead::generic_array::GenericArray;
3use aead::{Aead, NewAead};
4use aes_gcm::Aes256Gcm;
5use rand::RngCore;
6use rand::rngs::OsRng;
7use serde::Serialize;
8use serde::de::DeserializeOwned;
9
10use super::errors::{CryptoError, LbErrKind, LbResult, Unexpected};
11
12pub fn generate_key() -> AESKey {
13    let mut random_bytes = [0u8; 32];
14    OsRng.fill_bytes(&mut random_bytes);
15    random_bytes
16}
17
18pub fn encrypt<T: Serialize + DeserializeOwned>(
19    key: &AESKey, to_encrypt: &T,
20) -> LbResult<AESEncrypted<T>> {
21    let serialized = bincode::serialize(to_encrypt).map_unexpected()?;
22    let nonce = &generate_nonce();
23    let encrypted = convert_key(key)
24        .encrypt(GenericArray::from_slice(nonce), aead::Payload { msg: &serialized, aad: &[] })
25        .map_unexpected()?;
26    Ok(AESEncrypted::new(encrypted, nonce.to_vec()))
27}
28
29pub fn decrypt<T: DeserializeOwned>(key: &AESKey, to_decrypt: &AESEncrypted<T>) -> LbResult<T> {
30    let nonce = GenericArray::from_slice(&to_decrypt.nonce);
31    let decrypted = convert_key(key)
32        .decrypt(nonce, aead::Payload { msg: &to_decrypt.value, aad: &[] })
33        .map_err(|err| LbErrKind::Crypto(CryptoError::Decryption(err)))?;
34    let deserialized = bincode::deserialize(&decrypted).map_unexpected()?;
35    Ok(deserialized)
36}
37
38pub fn convert_key(to_convert: &AESKey) -> Aes256Gcm {
39    Aes256Gcm::new(&GenericArray::clone_from_slice(to_convert))
40}
41
42pub fn generate_nonce() -> [u8; 12] {
43    let mut result = [0u8; 12];
44    OsRng.fill_bytes(&mut result);
45    result
46}
47
48#[cfg(test)]
49mod unit_tests {
50    use uuid::Uuid;
51
52    use crate::model::symkey::{decrypt, encrypt, generate_key};
53
54    #[test]
55    fn test_generate_encrypt_decrypt() {
56        let key = generate_key();
57        let test_value = Uuid::new_v4().to_string();
58        let encrypted = encrypt(&key, &test_value).unwrap();
59        let decrypted = decrypt(&key, &encrypted).unwrap();
60        assert_eq!(test_value, decrypted)
61    }
62}