kms_aead/
kms_envelope_encryption.rs1use 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}