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