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 88 89
pub use sodiumoxide::crypto::aead::xchacha20poly1305_ietf::Nonce; use sodiumoxide::crypto::aead::xchacha20poly1305_ietf::{ gen_key, gen_nonce, open, seal, Key as UnderlyingKey, }; use crate::algo::{self as base, cipher::symmetric as symm}; #[derive(Clone)] pub struct Key { store: Vec<u8>, key: UnderlyingKey, } impl base::SafeGenerateKey for Key { type Settings = (); fn safe_generate(_: &Self::Settings) -> Self { let key = gen_key(); Self::new(key) } } impl symm::Key for Key {} impl Key { pub fn new(key: UnderlyingKey) -> Self { Self { store: key.as_ref().to_vec(), key: key, } } fn underlying(&self) -> &'_ UnderlyingKey { &self.key } } pub struct EncryptArgs { pub plaintext: Vec<u8>, pub aad: Option<Vec<u8>>, pub nonce: Option<Nonce>, } pub struct DecryptArgs { pub ciphertext: Vec<u8>, pub aad: Option<Vec<u8>>, pub nonce: Nonce, } pub struct Algo; impl base::Algo for Algo { type Key = Key; type ConstructionData = (); fn key_settings<'a>( &'a self, ) -> &'a <<Self as base::Algo>::Key as base::SafeGenerateKey>::Settings { &() } fn new(_: ()) -> Self { Self } } impl symm::Algo for Algo {} impl symm::CanEncrypt for Algo { type EKey = Key; type Input = EncryptArgs; type Error = symm::EncryptError; fn encrypt(&self, key: &Self::EKey, msg: &Self::Input) -> Result<Vec<u8>, Self::Error> { let nonce = if let Some(n) = msg.nonce { n } else { gen_nonce() }; Ok(seal( msg.plaintext.as_slice(), msg.aad.as_ref().map(|aad| aad.as_slice()), &nonce, key.underlying(), )) } } impl symm::CanDecrypt for Algo { type DKey = Key; type Input = DecryptArgs; type Error = symm::DecryptError; fn decrypt(&self, key: &Self::DKey, msg: &Self::Input) -> Result<Vec<u8>, Self::Error> { open( msg.ciphertext.as_slice(), msg.aad.as_ref().map(|aad| aad.as_slice()), &msg.nonce, key.underlying(), ) .map_err(|_| symm::DecryptError::Base) } }