core_crypto/mls_provider/
mod.rs1#![expect(unreachable_pub)]
3use std::sync::Arc;
4
5pub use core_crypto_keystore::{Database, DatabaseKey};
6
7mod crypto_provider;
8mod error;
9
10pub(crate) use crypto_provider::CRYPTO;
11pub use crypto_provider::RustCrypto;
12pub use error::{MlsProviderError, MlsProviderResult};
13use openmls_traits::{
14 crypto::OpenMlsCrypto,
15 types::{
16 AeadType, Ciphersuite, CryptoError, ExporterSecret, HashType, HpkeCiphertext, HpkeConfig, HpkeKeyPair,
17 KemOutput, SignatureScheme,
18 },
19};
20use wire_e2e_identity::PkiEnvironmentProvider;
21#[allow(unused)]
23pub use wire_e2e_identity::pki::{CertProfile, CertificateGenerationArgs, PkiKeypair};
24
25pub type RawEntropySeed = <rand_chacha::ChaCha20Rng as rand::SeedableRng>::Seed;
27
28#[derive(Debug, Clone, Default, PartialEq, Eq, zeroize::ZeroizeOnDrop)]
29#[repr(transparent)]
30pub struct EntropySeed(RawEntropySeed);
32
33impl EntropySeed {
34 pub const EXPECTED_LEN: usize = std::mem::size_of::<EntropySeed>() / std::mem::size_of::<u8>();
36
37 pub fn try_from_slice(data: &[u8]) -> MlsProviderResult<Self> {
39 if data.len() < Self::EXPECTED_LEN {
40 return Err(MlsProviderError::EntropySeedLengthError {
41 actual: data.len(),
42 expected: Self::EXPECTED_LEN,
43 });
44 }
45
46 let mut inner = RawEntropySeed::default();
47 inner.copy_from_slice(&data[..Self::EXPECTED_LEN]);
48
49 Ok(Self(inner))
50 }
51
52 pub fn from_raw(raw: RawEntropySeed) -> Self {
54 Self(raw)
55 }
56}
57
58impl std::ops::Deref for EntropySeed {
59 type Target = [u8];
60 fn deref(&self) -> &Self::Target {
61 &self.0
62 }
63}
64
65impl std::ops::DerefMut for EntropySeed {
66 fn deref_mut(&mut self) -> &mut Self::Target {
67 &mut self.0
68 }
69}
70
71#[derive(Debug, Clone)]
73pub struct MlsCryptoProvider {
74 crypto: Arc<RustCrypto>,
75 key_store: Database,
76 pki_env: PkiEnvironmentProvider,
77}
78
79impl MlsCryptoProvider {
80 pub fn new(key_store: Database) -> Self {
86 Self {
87 key_store,
88 crypto: Arc::clone(&CRYPTO),
89 pki_env: Default::default(),
90 }
91 }
92
93 pub fn new_with_pki_env(key_store: Database, pki_env: PkiEnvironmentProvider) -> Self {
95 Self {
96 key_store,
97 crypto: Arc::clone(&CRYPTO),
98 pki_env,
99 }
100 }
101
102 pub async fn new_transaction(&self) -> MlsProviderResult<()> {
105 self.key_store.new_transaction().await.map_err(Into::into)
106 }
107
108 pub async fn update_pki_env(&self, pki_env: Option<wire_e2e_identity::x509_check::revocation::PkiEnvironment>) {
110 self.pki_env.update_env(pki_env).await
111 }
112
113 pub async fn set_pki_environment_provider(&mut self, pki_env: Option<PkiEnvironmentProvider>) {
115 if let Some(pki_env) = pki_env {
116 self.pki_env = pki_env;
117 } else {
118 self.pki_env.update_env(None).await;
119 }
120 }
121
122 pub async fn is_pki_env_setup(&self) -> bool {
124 self.pki_env.is_env_setup().await
125 }
126
127 pub fn reseed(&self, entropy_seed: Option<EntropySeed>) -> MlsProviderResult<()> {
131 self.crypto.reseed(entropy_seed)
132 }
133
134 pub async fn close(&self) -> MlsProviderResult<()> {
138 self.key_store.close().await?;
139 Ok(())
140 }
141}
142
143impl openmls_traits::OpenMlsCryptoProvider for MlsCryptoProvider {
144 type CryptoProvider = RustCrypto;
145 type RandProvider = RustCrypto;
146 type KeyStoreProvider = Database;
147 type AuthenticationServiceProvider = PkiEnvironmentProvider;
148
149 fn crypto(&self) -> &Self::CryptoProvider {
150 &self.crypto
151 }
152
153 fn rand(&self) -> &Self::RandProvider {
154 &self.crypto
155 }
156
157 fn key_store(&self) -> &Self::KeyStoreProvider {
158 &self.key_store
159 }
160
161 fn authentication_service(&self) -> &Self::AuthenticationServiceProvider {
162 &self.pki_env
163 }
164}
165
166impl OpenMlsCrypto for &MlsCryptoProvider {
168 fn supports(&self, ciphersuite: Ciphersuite) -> Result<(), CryptoError> {
169 self.crypto.supports(ciphersuite)
170 }
171
172 fn supported_ciphersuites(&self) -> Vec<Ciphersuite> {
173 self.crypto.supported_ciphersuites()
174 }
175
176 fn hkdf_extract(
177 &self,
178 hash_type: HashType,
179 salt: &[u8],
180 ikm: &[u8],
181 ) -> Result<tls_codec::SecretVLBytes, CryptoError> {
182 self.crypto.hkdf_extract(hash_type, salt, ikm)
183 }
184
185 fn hkdf_expand(
186 &self,
187 hash_type: HashType,
188 prk: &[u8],
189 info: &[u8],
190 okm_len: usize,
191 ) -> Result<tls_codec::SecretVLBytes, CryptoError> {
192 self.crypto.hkdf_expand(hash_type, prk, info, okm_len)
193 }
194
195 fn hash(&self, hash_type: HashType, data: &[u8]) -> Result<Vec<u8>, CryptoError> {
196 self.crypto.hash(hash_type, data)
197 }
198
199 fn aead_encrypt(
200 &self,
201 alg: AeadType,
202 key: &[u8],
203 data: &[u8],
204 nonce: &[u8],
205 aad: &[u8],
206 ) -> Result<Vec<u8>, CryptoError> {
207 self.crypto.aead_encrypt(alg, key, data, nonce, aad)
208 }
209
210 fn aead_decrypt(
211 &self,
212 alg: AeadType,
213 key: &[u8],
214 ct_tag: &[u8],
215 nonce: &[u8],
216 aad: &[u8],
217 ) -> Result<Vec<u8>, CryptoError> {
218 self.crypto.aead_decrypt(alg, key, ct_tag, nonce, aad)
219 }
220
221 fn signature_key_gen(&self, alg: SignatureScheme) -> Result<(Vec<u8>, Vec<u8>), CryptoError> {
222 self.crypto.signature_key_gen(alg)
223 }
224
225 fn signature_public_key_len(&self, alg: SignatureScheme) -> usize {
226 self.crypto.signature_public_key_len(alg)
227 }
228
229 fn validate_signature_key(&self, alg: SignatureScheme, key: &[u8]) -> Result<(), CryptoError> {
230 self.crypto.validate_signature_key(alg, key)
231 }
232
233 fn verify_signature(
234 &self,
235 alg: SignatureScheme,
236 data: &[u8],
237 pk: &[u8],
238 signature: &[u8],
239 ) -> Result<(), CryptoError> {
240 self.crypto.verify_signature(alg, data, pk, signature)
241 }
242
243 fn sign(&self, alg: SignatureScheme, data: &[u8], key: &[u8]) -> Result<Vec<u8>, CryptoError> {
244 self.crypto.sign(alg, data, key)
245 }
246
247 fn hpke_seal(
248 &self,
249 config: HpkeConfig,
250 pk_r: &[u8],
251 info: &[u8],
252 aad: &[u8],
253 ptxt: &[u8],
254 ) -> Result<HpkeCiphertext, CryptoError> {
255 self.crypto.hpke_seal(config, pk_r, info, aad, ptxt)
256 }
257
258 fn hpke_open(
259 &self,
260 config: HpkeConfig,
261 input: &HpkeCiphertext,
262 sk_r: &[u8],
263 info: &[u8],
264 aad: &[u8],
265 ) -> Result<Vec<u8>, CryptoError> {
266 self.crypto.hpke_open(config, input, sk_r, info, aad)
267 }
268
269 fn hpke_setup_sender_and_export(
270 &self,
271 config: HpkeConfig,
272 pk_r: &[u8],
273 info: &[u8],
274 exporter_context: &[u8],
275 exporter_length: usize,
276 ) -> Result<(KemOutput, ExporterSecret), CryptoError> {
277 self.crypto
278 .hpke_setup_sender_and_export(config, pk_r, info, exporter_context, exporter_length)
279 }
280
281 fn hpke_setup_receiver_and_export(
282 &self,
283 config: HpkeConfig,
284 enc: &[u8],
285 sk_r: &[u8],
286 info: &[u8],
287 exporter_context: &[u8],
288 exporter_length: usize,
289 ) -> Result<ExporterSecret, CryptoError> {
290 self.crypto
291 .hpke_setup_receiver_and_export(config, enc, sk_r, info, exporter_context, exporter_length)
292 }
293
294 fn derive_hpke_keypair(&self, config: HpkeConfig, ikm: &[u8]) -> Result<HpkeKeyPair, CryptoError> {
295 self.crypto.derive_hpke_keypair(config, ikm)
296 }
297}