kms_aead/
kms_envelope_encryption.rs

1use crate::ring_encryption::{RingAeadEncryption, RingAeadEncryptionOptions};
2use crate::*;
3use async_trait::*;
4use ring::rand::SystemRandom;
5use rsb_derive::*;
6use secret_vault_value::SecretValue;
7
8#[async_trait]
9pub trait KmsAeadRingEncryptionProvider {
10    async fn encrypt_data_encryption_key(
11        &self,
12        encryption_key: &DataEncryptionKey,
13    ) -> KmsAeadResult<EncryptedDataEncryptionKey>;
14
15    async fn decrypt_data_encryption_key(
16        &self,
17        encrypted_key: &EncryptedDataEncryptionKey,
18    ) -> KmsAeadResult<DataEncryptionKey>;
19
20    async fn generate_encryption_key(
21        &self,
22        aead_encryption: &RingAeadEncryption,
23    ) -> KmsAeadResult<DataEncryptionKey>;
24}
25
26pub struct KmsAeadRingEnvelopeEncryption<P>
27where
28    P: KmsAeadRingEncryptionProvider + Send + Sync,
29{
30    provider: P,
31    aead_encryption: RingAeadEncryption,
32}
33
34#[derive(Debug, Clone, Builder)]
35pub struct KmsAeadRingEnvelopeEncryptionOptions {
36    #[default = "RingAeadEncryptionOptions::new()"]
37    pub encryption_options: RingAeadEncryptionOptions,
38}
39
40impl<P> KmsAeadRingEnvelopeEncryption<P>
41where
42    P: KmsAeadRingEncryptionProvider + Send + Sync,
43{
44    pub async fn new(provider: P) -> KmsAeadResult<Self> {
45        Self::with_algorithm(provider, &ring::aead::CHACHA20_POLY1305).await
46    }
47
48    pub async fn with_algorithm(
49        provider: P,
50        algo: &'static ring::aead::Algorithm,
51    ) -> KmsAeadResult<Self> {
52        Self::with_algorithm_options(provider, algo, KmsAeadRingEnvelopeEncryptionOptions::new())
53            .await
54    }
55
56    pub async fn with_options(
57        provider: P,
58        options: KmsAeadRingEnvelopeEncryptionOptions,
59    ) -> KmsAeadResult<Self> {
60        Self::with_algorithm_options(provider, &ring::aead::CHACHA20_POLY1305, options).await
61    }
62
63    pub async fn with_algorithm_options(
64        provider: P,
65        algo: &'static ring::aead::Algorithm,
66        options: KmsAeadRingEnvelopeEncryptionOptions,
67    ) -> KmsAeadResult<Self> {
68        let secure_rand = SystemRandom::new();
69        let aead_encryption = RingAeadEncryption::with_algorithm_options(
70            algo,
71            secure_rand,
72            options.encryption_options,
73        )?;
74
75        Ok(Self {
76            provider,
77            aead_encryption,
78        })
79    }
80
81    async fn new_dek(&self) -> KmsAeadResult<(DataEncryptionKey, EncryptedDataEncryptionKey)> {
82        let dek = self
83            .provider
84            .generate_encryption_key(&self.aead_encryption)
85            .await?;
86
87        let encrypted_dek = self.provider.encrypt_data_encryption_key(&dek).await?;
88
89        Ok((dek, encrypted_dek))
90    }
91
92    async fn encrypt_value_with_new_dek<Aad>(
93        &self,
94        aad: &Aad,
95        plain_text: &SecretValue,
96    ) -> KmsAeadResult<(CipherText, EncryptedDataEncryptionKey)>
97    where
98        Aad: AsRef<[u8]> + Send + Sync + 'static,
99    {
100        let (new_dek, new_encrypted_dek) = self.new_dek().await?;
101
102        let cipher_text = self
103            .aead_encryption
104            .encrypt_value(aad, plain_text, &new_dek)
105            .await?;
106
107        Ok((cipher_text, new_encrypted_dek))
108    }
109}
110
111#[async_trait]
112impl<Aad, P> KmsAeadEnvelopeEncryption<Aad> for KmsAeadRingEnvelopeEncryption<P>
113where
114    Aad: AsRef<[u8]> + Send + Sync + 'static,
115    P: KmsAeadRingEncryptionProvider + Send + Sync,
116{
117    async fn encrypt_value(
118        &self,
119        aad: &Aad,
120        plain_text: &SecretValue,
121    ) -> KmsAeadResult<CipherTextWithEncryptedKey> {
122        let (cipher_text, dek) = self.encrypt_value_with_new_dek(aad, plain_text).await?;
123        Ok(CipherTextWithEncryptedKey::new(&cipher_text, &dek))
124    }
125
126    async fn decrypt_value(
127        &self,
128        aad: &Aad,
129        cipher_text: &CipherTextWithEncryptedKey,
130    ) -> KmsAeadResult<SecretValue> {
131        let (cipher_text, encrypted_dek) = cipher_text.separate()?;
132        self.decrypt_value_with_encrypted_dek(aad, &cipher_text, &encrypted_dek)
133            .await
134    }
135
136    async fn encrypt_value_with_dek(
137        &self,
138        aad: &Aad,
139        plain_text: &SecretValue,
140        dek: &DataEncryptionKey,
141    ) -> KmsAeadResult<CipherText> {
142        let cipher_text = self
143            .aead_encryption
144            .encrypt_value(aad, plain_text, dek)
145            .await?;
146
147        Ok(cipher_text)
148    }
149
150    async fn encrypt_value_with_encrypted_dek(
151        &self,
152        aad: &Aad,
153        plain_text: &SecretValue,
154        dek: &EncryptedDataEncryptionKey,
155    ) -> KmsAeadResult<CipherText> {
156        let dek = self.provider.decrypt_data_encryption_key(dek).await?;
157
158        self.encrypt_value_with_dek(aad, plain_text, &dek).await
159    }
160
161    async fn decrypt_value_with_dek(
162        &self,
163        aad: &Aad,
164        cipher_text: &CipherText,
165        data_encryption_key: &DataEncryptionKey,
166    ) -> KmsAeadResult<SecretValue> {
167        self.aead_encryption
168            .decrypt_value(aad, cipher_text, data_encryption_key)
169            .await
170    }
171    async fn decrypt_value_with_encrypted_dek(
172        &self,
173        aad: &Aad,
174        cipher_text: &CipherText,
175        encrypted_data_encryption_key: &EncryptedDataEncryptionKey,
176    ) -> KmsAeadResult<SecretValue> {
177        let dek = self
178            .provider
179            .decrypt_data_encryption_key(encrypted_data_encryption_key)
180            .await?;
181
182        self.decrypt_value_with_dek(aad, cipher_text, &dek).await
183    }
184
185    async fn generate_new_dek(
186        &self,
187    ) -> KmsAeadResult<(DataEncryptionKey, EncryptedDataEncryptionKey)> {
188        self.new_dek().await
189    }
190}