1use openmls_rust_crypto::{MemoryStorage, OpenMlsRustCrypto, RustCrypto};
11use openmls_traits::{
12 crypto::OpenMlsCrypto,
13 types::{
14 AeadType, Ciphersuite, CryptoError, ExporterSecret, HashType, HpkeCiphertext, HpkeConfig,
15 HpkeKeyPair, KemOutput, SignatureScheme,
16 },
17 OpenMlsProvider,
18};
19use tls_codec::SecretVLBytes;
20
21pub struct RestrictedCrypto {
24 inner: RustCrypto,
25 allowed: Vec<Ciphersuite>,
26}
27
28impl OpenMlsCrypto for RestrictedCrypto {
29 fn supports(&self, ciphersuite: Ciphersuite) -> Result<(), CryptoError> {
30 if self.allowed.contains(&ciphersuite) {
31 Ok(())
32 } else {
33 Err(CryptoError::UnsupportedCiphersuite)
34 }
35 }
36
37 fn supported_ciphersuites(&self) -> Vec<Ciphersuite> {
38 self.allowed.clone()
39 }
40
41 fn hkdf_extract(
42 &self,
43 hash_type: HashType,
44 salt: &[u8],
45 ikm: &[u8],
46 ) -> Result<SecretVLBytes, CryptoError> {
47 self.inner.hkdf_extract(hash_type, salt, ikm)
48 }
49
50 fn hmac(
51 &self,
52 hash_type: HashType,
53 key: &[u8],
54 message: &[u8],
55 ) -> Result<SecretVLBytes, CryptoError> {
56 self.inner.hmac(hash_type, key, message)
57 }
58
59 fn hkdf_expand(
60 &self,
61 hash_type: HashType,
62 prk: &[u8],
63 info: &[u8],
64 okm_len: usize,
65 ) -> Result<SecretVLBytes, CryptoError> {
66 self.inner.hkdf_expand(hash_type, prk, info, okm_len)
67 }
68
69 fn hash(&self, hash_type: HashType, data: &[u8]) -> Result<Vec<u8>, CryptoError> {
70 self.inner.hash(hash_type, data)
71 }
72
73 fn aead_encrypt(
74 &self,
75 alg: AeadType,
76 key: &[u8],
77 data: &[u8],
78 nonce: &[u8],
79 aad: &[u8],
80 ) -> Result<Vec<u8>, CryptoError> {
81 self.inner.aead_encrypt(alg, key, data, nonce, aad)
82 }
83
84 fn aead_decrypt(
85 &self,
86 alg: AeadType,
87 key: &[u8],
88 ct_tag: &[u8],
89 nonce: &[u8],
90 aad: &[u8],
91 ) -> Result<Vec<u8>, CryptoError> {
92 self.inner.aead_decrypt(alg, key, ct_tag, nonce, aad)
93 }
94
95 fn signature_key_gen(&self, alg: SignatureScheme) -> Result<(Vec<u8>, Vec<u8>), CryptoError> {
96 self.inner.signature_key_gen(alg)
97 }
98
99 fn verify_signature(
100 &self,
101 alg: SignatureScheme,
102 data: &[u8],
103 pk: &[u8],
104 signature: &[u8],
105 ) -> Result<(), CryptoError> {
106 self.inner.verify_signature(alg, data, pk, signature)
107 }
108
109 fn sign(&self, alg: SignatureScheme, data: &[u8], key: &[u8]) -> Result<Vec<u8>, CryptoError> {
110 self.inner.sign(alg, data, key)
111 }
112
113 fn hpke_seal(
114 &self,
115 config: HpkeConfig,
116 pk_r: &[u8],
117 info: &[u8],
118 aad: &[u8],
119 ptxt: &[u8],
120 ) -> Result<HpkeCiphertext, CryptoError> {
121 self.inner.hpke_seal(config, pk_r, info, aad, ptxt)
122 }
123
124 fn hpke_open(
125 &self,
126 config: HpkeConfig,
127 input: &HpkeCiphertext,
128 sk_r: &[u8],
129 info: &[u8],
130 aad: &[u8],
131 ) -> Result<Vec<u8>, CryptoError> {
132 self.inner.hpke_open(config, input, sk_r, info, aad)
133 }
134
135 fn hpke_setup_sender_and_export(
136 &self,
137 config: HpkeConfig,
138 pk_r: &[u8],
139 info: &[u8],
140 exporter_context: &[u8],
141 exporter_length: usize,
142 ) -> Result<(KemOutput, ExporterSecret), CryptoError> {
143 self.inner.hpke_setup_sender_and_export(
144 config,
145 pk_r,
146 info,
147 exporter_context,
148 exporter_length,
149 )
150 }
151
152 fn hpke_setup_receiver_and_export(
153 &self,
154 config: HpkeConfig,
155 enc: &[u8],
156 sk_r: &[u8],
157 info: &[u8],
158 exporter_context: &[u8],
159 exporter_length: usize,
160 ) -> Result<ExporterSecret, CryptoError> {
161 self.inner.hpke_setup_receiver_and_export(
162 config,
163 enc,
164 sk_r,
165 info,
166 exporter_context,
167 exporter_length,
168 )
169 }
170
171 fn derive_hpke_keypair(
172 &self,
173 config: HpkeConfig,
174 ikm: &[u8],
175 ) -> Result<HpkeKeyPair, CryptoError> {
176 self.inner.derive_hpke_keypair(config, ikm)
177 }
178
179 #[cfg(feature = "targeted-messages-draft")]
180 fn hpke_open_psk(
181 &self,
182 config: HpkeConfig,
183 input: &HpkeCiphertext,
184 sk_r: &[u8],
185 info: &[u8],
186 aad: &[u8],
187 psk: &[u8],
188 psk_id: &[u8],
189 ) -> Result<Vec<u8>, CryptoError> {
190 self.inner
191 .hpke_open_psk(config, input, sk_r, info, aad, psk, psk_id)
192 }
193
194 #[cfg(feature = "targeted-messages-draft")]
195 fn hpke_seal_psk_resolved_aad<F, E>(
196 &self,
197 config: HpkeConfig,
198 pk_r: &[u8],
199 info: &[u8],
200 ptxt: &[u8],
201 psk: &[u8],
202 psk_id: &[u8],
203 aad_builder: F,
204 ) -> Result<HpkeCiphertext, openmls_traits::crypto::HpkeSealPskResolvedAadError<E>>
205 where
206 Self: Sized,
207 F: FnOnce(&[u8]) -> Result<Vec<u8>, E>,
208 {
209 self.inner
210 .hpke_seal_psk_resolved_aad(config, pk_r, info, ptxt, psk, psk_id, aad_builder)
211 }
212
213 #[cfg(feature = "virtual-clients-draft")]
214 fn ff1_aes128_encrypt(&self, key: &[u8; 16], plaintext: u32) -> Result<u32, CryptoError> {
215 self.inner.ff1_aes128_encrypt(key, plaintext)
216 }
217
218 #[cfg(feature = "virtual-clients-draft")]
219 fn ff1_aes128_decrypt(&self, key: &[u8; 16], ciphertext: u32) -> Result<u32, CryptoError> {
220 self.inner.ff1_aes128_decrypt(key, ciphertext)
221 }
222}
223
224pub struct RestrictedProvider {
227 crypto: RestrictedCrypto,
228 inner: OpenMlsRustCrypto,
229}
230
231impl RestrictedProvider {
232 pub fn new(allowed: Vec<Ciphersuite>) -> Self {
235 Self {
236 crypto: RestrictedCrypto {
237 inner: RustCrypto::default(),
238 allowed,
239 },
240 inner: OpenMlsRustCrypto::default(),
241 }
242 }
243
244 pub fn inner(&self) -> &OpenMlsRustCrypto {
248 &self.inner
249 }
250}
251
252impl OpenMlsProvider for RestrictedProvider {
253 type CryptoProvider = RestrictedCrypto;
254 type RandProvider = RustCrypto;
255 type StorageProvider = MemoryStorage;
256
257 fn storage(&self) -> &Self::StorageProvider {
258 self.inner.storage()
259 }
260
261 fn crypto(&self) -> &Self::CryptoProvider {
262 &self.crypto
263 }
264
265 fn rand(&self) -> &Self::RandProvider {
266 self.inner.rand()
267 }
268}