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(
196 &self,
197 config: HpkeConfig,
198 pk_r: &[u8],
199 info: &[u8],
200 aad: &[u8],
201 ptxt: &[u8],
202 psk: &[u8],
203 psk_id: &[u8],
204 ) -> Result<HpkeCiphertext, CryptoError> {
205 self.inner
206 .hpke_seal_psk(config, pk_r, info, aad, ptxt, psk, psk_id)
207 }
208
209 #[cfg(feature = "virtual-clients-draft")]
210 fn ff1_aes128_encrypt(&self, key: &[u8; 16], plaintext: u32) -> Result<u32, CryptoError> {
211 self.inner.ff1_aes128_encrypt(key, plaintext)
212 }
213
214 #[cfg(feature = "virtual-clients-draft")]
215 fn ff1_aes128_decrypt(&self, key: &[u8; 16], ciphertext: u32) -> Result<u32, CryptoError> {
216 self.inner.ff1_aes128_decrypt(key, ciphertext)
217 }
218}
219
220pub struct RestrictedProvider {
223 crypto: RestrictedCrypto,
224 inner: OpenMlsRustCrypto,
225}
226
227impl RestrictedProvider {
228 pub fn new(allowed: Vec<Ciphersuite>) -> Self {
231 Self {
232 crypto: RestrictedCrypto {
233 inner: RustCrypto::default(),
234 allowed,
235 },
236 inner: OpenMlsRustCrypto::default(),
237 }
238 }
239
240 pub fn inner(&self) -> &OpenMlsRustCrypto {
244 &self.inner
245 }
246}
247
248impl OpenMlsProvider for RestrictedProvider {
249 type CryptoProvider = RestrictedCrypto;
250 type RandProvider = RustCrypto;
251 type StorageProvider = MemoryStorage;
252
253 fn storage(&self) -> &Self::StorageProvider {
254 self.inner.storage()
255 }
256
257 fn crypto(&self) -> &Self::CryptoProvider {
258 &self.crypto
259 }
260
261 fn rand(&self) -> &Self::RandProvider {
262 self.inner.rand()
263 }
264}