trussed_core/
mechanisms.rs

1use crate::{
2    api::reply,
3    client::{crypto::CryptoClient, ClientError, ClientResult},
4    types::{
5        KeyId, KeySerialization, Location, Mechanism, MediumData, Message, ShortData,
6        SignatureSerialization, StorageAttributes,
7    },
8};
9
10#[cfg(feature = "aes256-cbc")]
11pub trait Aes256Cbc: CryptoClient {
12    fn decrypt_aes256cbc<'c>(
13        &'c mut self,
14        key: KeyId,
15        message: &[u8],
16        iv: &[u8],
17    ) -> ClientResult<'c, reply::Decrypt, Self> {
18        self.decrypt(Mechanism::Aes256Cbc, key, message, &[], iv, &[])
19    }
20
21    fn wrap_key_aes256cbc(
22        &mut self,
23        wrapping_key: KeyId,
24        key: KeyId,
25        iv: Option<&[u8; 16]>,
26    ) -> ClientResult<'_, reply::WrapKey, Self> {
27        self.wrap_key(
28            Mechanism::Aes256Cbc,
29            wrapping_key,
30            key,
31            &[],
32            iv.and_then(|iv| ShortData::from_slice(iv).ok()),
33        )
34    }
35}
36
37#[cfg(feature = "chacha8-poly1305")]
38pub trait Chacha8Poly1305: CryptoClient {
39    fn decrypt_chacha8poly1305<'c>(
40        &'c mut self,
41        key: KeyId,
42        message: &[u8],
43        associated_data: &[u8],
44        nonce: &[u8],
45        tag: &[u8],
46    ) -> ClientResult<'c, reply::Decrypt, Self> {
47        self.decrypt(
48            Mechanism::Chacha8Poly1305,
49            key,
50            message,
51            associated_data,
52            nonce,
53            tag,
54        )
55    }
56
57    fn encrypt_chacha8poly1305<'c>(
58        &'c mut self,
59        key: KeyId,
60        message: &[u8],
61        associated_data: &[u8],
62        nonce: Option<&[u8; 12]>,
63    ) -> ClientResult<'c, reply::Encrypt, Self> {
64        self.encrypt(
65            Mechanism::Chacha8Poly1305,
66            key,
67            message,
68            associated_data,
69            nonce.and_then(|nonce| ShortData::from_slice(nonce).ok()),
70        )
71    }
72
73    fn generate_chacha8poly1305_key(
74        &mut self,
75        persistence: Location,
76    ) -> ClientResult<'_, reply::GenerateKey, Self> {
77        self.generate_key(
78            Mechanism::Chacha8Poly1305,
79            StorageAttributes::new().set_persistence(persistence),
80        )
81    }
82
83    fn unwrap_key_chacha8poly1305<'c>(
84        &'c mut self,
85        wrapping_key: KeyId,
86        wrapped_key: &[u8],
87        associated_data: &[u8],
88        location: Location,
89    ) -> ClientResult<'c, reply::UnwrapKey, Self> {
90        self.unwrap_key(
91            Mechanism::Chacha8Poly1305,
92            wrapping_key,
93            Message::from_slice(wrapped_key).map_err(|_| ClientError::DataTooLarge)?,
94            associated_data,
95            &[],
96            StorageAttributes::new().set_persistence(location),
97        )
98    }
99
100    fn wrap_key_chacha8poly1305<'c>(
101        &'c mut self,
102        wrapping_key: KeyId,
103        key: KeyId,
104        associated_data: &[u8],
105        nonce: Option<&[u8; 12]>,
106    ) -> ClientResult<'c, reply::WrapKey, Self> {
107        self.wrap_key(
108            Mechanism::Chacha8Poly1305,
109            wrapping_key,
110            key,
111            associated_data,
112            nonce.and_then(|nonce| ShortData::from_slice(nonce).ok()),
113        )
114    }
115}
116
117#[cfg(feature = "hmac-blake2s")]
118pub trait HmacBlake2s: CryptoClient {
119    fn hmacblake2s_derive_key(
120        &mut self,
121        base_key: KeyId,
122        message: &[u8],
123        persistence: Location,
124    ) -> ClientResult<'_, reply::DeriveKey, Self> {
125        self.derive_key(
126            Mechanism::HmacBlake2s,
127            base_key,
128            Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?),
129            StorageAttributes::new().set_persistence(persistence),
130        )
131    }
132
133    fn sign_hmacblake2s<'c>(
134        &'c mut self,
135        key: KeyId,
136        message: &[u8],
137    ) -> ClientResult<'c, reply::Sign, Self> {
138        self.sign(
139            Mechanism::HmacBlake2s,
140            key,
141            message,
142            SignatureSerialization::Raw,
143        )
144    }
145}
146
147#[cfg(feature = "hmac-sha1")]
148pub trait HmacSha1: CryptoClient {
149    fn hmacsha1_derive_key(
150        &mut self,
151        base_key: KeyId,
152        message: &[u8],
153        persistence: Location,
154    ) -> ClientResult<'_, reply::DeriveKey, Self> {
155        self.derive_key(
156            Mechanism::HmacSha1,
157            base_key,
158            Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?),
159            StorageAttributes::new().set_persistence(persistence),
160        )
161    }
162
163    fn sign_hmacsha1<'c>(
164        &'c mut self,
165        key: KeyId,
166        message: &[u8],
167    ) -> ClientResult<'c, reply::Sign, Self> {
168        self.sign(
169            Mechanism::HmacSha1,
170            key,
171            message,
172            SignatureSerialization::Raw,
173        )
174    }
175}
176
177#[cfg(feature = "hmac-sha256")]
178pub trait HmacSha256: CryptoClient {
179    fn hmacsha256_derive_key(
180        &mut self,
181        base_key: KeyId,
182        message: &[u8],
183        persistence: Location,
184    ) -> ClientResult<'_, reply::DeriveKey, Self> {
185        self.derive_key(
186            Mechanism::HmacSha256,
187            base_key,
188            Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?),
189            StorageAttributes::new().set_persistence(persistence),
190        )
191    }
192
193    fn sign_hmacsha256<'c>(
194        &'c mut self,
195        key: KeyId,
196        message: &[u8],
197    ) -> ClientResult<'c, reply::Sign, Self> {
198        self.sign(
199            Mechanism::HmacSha256,
200            key,
201            message,
202            SignatureSerialization::Raw,
203        )
204    }
205}
206
207#[cfg(feature = "hmac-sha512")]
208pub trait HmacSha512: CryptoClient {
209    fn hmacsha512_derive_key(
210        &mut self,
211        base_key: KeyId,
212        message: &[u8],
213        persistence: Location,
214    ) -> ClientResult<'_, reply::DeriveKey, Self> {
215        self.derive_key(
216            Mechanism::HmacSha512,
217            base_key,
218            Some(MediumData::from_slice(message).map_err(|_| ClientError::DataTooLarge)?),
219            StorageAttributes::new().set_persistence(persistence),
220        )
221    }
222
223    fn sign_hmacsha512<'c>(
224        &'c mut self,
225        key: KeyId,
226        message: &[u8],
227    ) -> ClientResult<'c, reply::Sign, Self> {
228        self.sign(
229            Mechanism::HmacSha512,
230            key,
231            message,
232            SignatureSerialization::Raw,
233        )
234    }
235}
236
237#[cfg(feature = "ed255")]
238pub trait Ed255: CryptoClient {
239    fn generate_ed255_private_key(
240        &mut self,
241        persistence: Location,
242    ) -> ClientResult<'_, reply::GenerateKey, Self> {
243        self.generate_key(
244            Mechanism::Ed255,
245            StorageAttributes::new().set_persistence(persistence),
246        )
247    }
248
249    fn derive_ed255_public_key(
250        &mut self,
251        private_key: KeyId,
252        persistence: Location,
253    ) -> ClientResult<'_, reply::DeriveKey, Self> {
254        self.derive_key(
255            Mechanism::Ed255,
256            private_key,
257            None,
258            StorageAttributes::new().set_persistence(persistence),
259        )
260    }
261
262    fn deserialize_ed255_key<'c>(
263        &'c mut self,
264        serialized_key: &[u8],
265        format: KeySerialization,
266        attributes: StorageAttributes,
267    ) -> ClientResult<'c, reply::DeserializeKey, Self> {
268        self.deserialize_key(Mechanism::Ed255, serialized_key, format, attributes)
269    }
270
271    fn serialize_ed255_key(
272        &mut self,
273        key: KeyId,
274        format: KeySerialization,
275    ) -> ClientResult<'_, reply::SerializeKey, Self> {
276        self.serialize_key(Mechanism::Ed255, key, format)
277    }
278
279    fn sign_ed255<'c>(
280        &'c mut self,
281        key: KeyId,
282        message: &[u8],
283    ) -> ClientResult<'c, reply::Sign, Self> {
284        self.sign(Mechanism::Ed255, key, message, SignatureSerialization::Raw)
285    }
286
287    fn verify_ed255<'c>(
288        &'c mut self,
289        key: KeyId,
290        message: &[u8],
291        signature: &[u8],
292    ) -> ClientResult<'c, reply::Verify, Self> {
293        self.verify(
294            Mechanism::Ed255,
295            key,
296            message,
297            signature,
298            SignatureSerialization::Raw,
299        )
300    }
301}
302
303#[cfg(feature = "p256")]
304pub trait P256: CryptoClient {
305    fn generate_p256_private_key(
306        &mut self,
307        persistence: Location,
308    ) -> ClientResult<'_, reply::GenerateKey, Self> {
309        self.generate_key(
310            Mechanism::P256,
311            StorageAttributes::new().set_persistence(persistence),
312        )
313    }
314
315    fn derive_p256_public_key(
316        &mut self,
317        private_key: KeyId,
318        persistence: Location,
319    ) -> ClientResult<'_, reply::DeriveKey, Self> {
320        self.derive_key(
321            Mechanism::P256,
322            private_key,
323            None,
324            StorageAttributes::new().set_persistence(persistence),
325        )
326    }
327
328    fn deserialize_p256_key<'c>(
329        &'c mut self,
330        serialized_key: &[u8],
331        format: KeySerialization,
332        attributes: StorageAttributes,
333    ) -> ClientResult<'c, reply::DeserializeKey, Self> {
334        self.deserialize_key(Mechanism::P256, serialized_key, format, attributes)
335    }
336
337    fn serialize_p256_key(
338        &mut self,
339        key: KeyId,
340        format: KeySerialization,
341    ) -> ClientResult<'_, reply::SerializeKey, Self> {
342        self.serialize_key(Mechanism::P256, key, format)
343    }
344
345    // generally, don't offer multiple versions of a mechanism, if possible.
346    // try using the simplest when given the choice.
347    // hashing is something users can do themselves hopefully :)
348    //
349    // on the other hand: if users need sha256, then if the service runs in secure trustzone
350    // domain, we'll maybe need two copies of the sha2 code
351    fn sign_p256<'c>(
352        &'c mut self,
353        key: KeyId,
354        message: &[u8],
355        format: SignatureSerialization,
356    ) -> ClientResult<'c, reply::Sign, Self> {
357        self.sign(Mechanism::P256, key, message, format)
358    }
359
360    fn verify_p256<'c>(
361        &'c mut self,
362        key: KeyId,
363        message: &[u8],
364        signature: &[u8],
365    ) -> ClientResult<'c, reply::Verify, Self> {
366        self.verify(
367            Mechanism::P256,
368            key,
369            message,
370            signature,
371            SignatureSerialization::Raw,
372        )
373    }
374
375    fn agree_p256(
376        &mut self,
377        private_key: KeyId,
378        public_key: KeyId,
379        persistence: Location,
380    ) -> ClientResult<'_, reply::Agree, Self> {
381        self.agree(
382            Mechanism::P256,
383            private_key,
384            public_key,
385            StorageAttributes::new().set_persistence(persistence),
386        )
387    }
388}
389
390#[cfg(feature = "p384")]
391pub trait P384: CryptoClient {
392    fn generate_p384_private_key(
393        &mut self,
394        persistence: Location,
395    ) -> ClientResult<'_, reply::GenerateKey, Self> {
396        self.generate_key(
397            Mechanism::P384,
398            StorageAttributes::new().set_persistence(persistence),
399        )
400    }
401
402    fn derive_p384_public_key(
403        &mut self,
404        private_key: KeyId,
405        persistence: Location,
406    ) -> ClientResult<'_, reply::DeriveKey, Self> {
407        self.derive_key(
408            Mechanism::P384,
409            private_key,
410            None,
411            StorageAttributes::new().set_persistence(persistence),
412        )
413    }
414
415    fn deserialize_p384_key<'c>(
416        &'c mut self,
417        serialized_key: &[u8],
418        format: KeySerialization,
419        attributes: StorageAttributes,
420    ) -> ClientResult<'c, reply::DeserializeKey, Self> {
421        self.deserialize_key(Mechanism::P384, serialized_key, format, attributes)
422    }
423
424    fn serialize_p384_key(
425        &mut self,
426        key: KeyId,
427        format: KeySerialization,
428    ) -> ClientResult<'_, reply::SerializeKey, Self> {
429        self.serialize_key(Mechanism::P384, key, format)
430    }
431
432    // generally, don't offer multiple versions of a mechanism, if possible.
433    // try using the simplest when given the choice.
434    // hashing is something users can do themselves hopefully :)
435    //
436    // on the other hand: if users need sha256, then if the service runs in secure trustzone
437    // domain, we'll maybe need two copies of the sha2 code
438    fn sign_p384<'c>(
439        &'c mut self,
440        key: KeyId,
441        message: &[u8],
442        format: SignatureSerialization,
443    ) -> ClientResult<'c, reply::Sign, Self> {
444        self.sign(Mechanism::P384, key, message, format)
445    }
446
447    fn verify_p384<'c>(
448        &'c mut self,
449        key: KeyId,
450        message: &[u8],
451        signature: &[u8],
452    ) -> ClientResult<'c, reply::Verify, Self> {
453        self.verify(
454            Mechanism::P384,
455            key,
456            message,
457            signature,
458            SignatureSerialization::Raw,
459        )
460    }
461
462    fn agree_p384(
463        &mut self,
464        private_key: KeyId,
465        public_key: KeyId,
466        persistence: Location,
467    ) -> ClientResult<'_, reply::Agree, Self> {
468        self.agree(
469            Mechanism::P384,
470            private_key,
471            public_key,
472            StorageAttributes::new().set_persistence(persistence),
473        )
474    }
475}
476
477#[cfg(feature = "p521")]
478pub trait P521: CryptoClient {
479    fn generate_p521_private_key(
480        &mut self,
481        persistence: Location,
482    ) -> ClientResult<'_, reply::GenerateKey, Self> {
483        self.generate_key(
484            Mechanism::P521,
485            StorageAttributes::new().set_persistence(persistence),
486        )
487    }
488
489    fn derive_p521_public_key(
490        &mut self,
491        private_key: KeyId,
492        persistence: Location,
493    ) -> ClientResult<'_, reply::DeriveKey, Self> {
494        self.derive_key(
495            Mechanism::P521,
496            private_key,
497            None,
498            StorageAttributes::new().set_persistence(persistence),
499        )
500    }
501
502    fn deserialize_p521_key<'c>(
503        &'c mut self,
504        serialized_key: &[u8],
505        format: KeySerialization,
506        attributes: StorageAttributes,
507    ) -> ClientResult<'c, reply::DeserializeKey, Self> {
508        self.deserialize_key(Mechanism::P521, serialized_key, format, attributes)
509    }
510
511    fn serialize_p521_key(
512        &mut self,
513        key: KeyId,
514        format: KeySerialization,
515    ) -> ClientResult<'_, reply::SerializeKey, Self> {
516        self.serialize_key(Mechanism::P521, key, format)
517    }
518
519    // generally, don't offer multiple versions of a mechanism, if possible.
520    // try using the simplest when given the choice.
521    // hashing is something users can do themselves hopefully :)
522    //
523    // on the other hand: if users need sha256, then if the service runs in secure trustzone
524    // domain, we'll maybe need two copies of the sha2 code
525    fn sign_p521<'c>(
526        &'c mut self,
527        key: KeyId,
528        message: &[u8],
529        format: SignatureSerialization,
530    ) -> ClientResult<'c, reply::Sign, Self> {
531        self.sign(Mechanism::P521, key, message, format)
532    }
533
534    fn verify_p521<'c>(
535        &'c mut self,
536        key: KeyId,
537        message: &[u8],
538        signature: &[u8],
539    ) -> ClientResult<'c, reply::Verify, Self> {
540        self.verify(
541            Mechanism::P521,
542            key,
543            message,
544            signature,
545            SignatureSerialization::Raw,
546        )
547    }
548
549    fn agree_p521(
550        &mut self,
551        private_key: KeyId,
552        public_key: KeyId,
553        persistence: Location,
554    ) -> ClientResult<'_, reply::Agree, Self> {
555        self.agree(
556            Mechanism::P521,
557            private_key,
558            public_key,
559            StorageAttributes::new().set_persistence(persistence),
560        )
561    }
562}
563
564#[cfg(feature = "sha256")]
565pub trait Sha256: CryptoClient {
566    fn sha256_derive_key(
567        &mut self,
568        shared_key: KeyId,
569        persistence: Location,
570    ) -> ClientResult<'_, reply::DeriveKey, Self> {
571        self.derive_key(
572            Mechanism::Sha256,
573            shared_key,
574            None,
575            StorageAttributes::new().set_persistence(persistence),
576        )
577    }
578
579    fn hash_sha256<'c>(&'c mut self, message: &[u8]) -> ClientResult<'c, reply::Hash, Self> {
580        self.hash(
581            Mechanism::Sha256,
582            Message::from_slice(message).map_err(|_| ClientError::DataTooLarge)?,
583        )
584    }
585}
586
587#[cfg(feature = "tdes")]
588pub trait Tdes: CryptoClient {
589    fn decrypt_tdes<'c>(
590        &'c mut self,
591        key: KeyId,
592        message: &[u8],
593    ) -> ClientResult<'c, reply::Decrypt, Self> {
594        self.decrypt(Mechanism::Tdes, key, message, &[], &[], &[])
595    }
596
597    fn encrypt_tdes<'c>(
598        &'c mut self,
599        key: KeyId,
600        message: &[u8],
601    ) -> ClientResult<'c, reply::Encrypt, Self> {
602        self.encrypt(Mechanism::Tdes, key, message, &[], None)
603    }
604}
605
606#[cfg(feature = "totp")]
607pub trait Totp: CryptoClient {
608    fn sign_totp(&mut self, key: KeyId, timestamp: u64) -> ClientResult<'_, reply::Sign, Self> {
609        self.sign(
610            Mechanism::Totp,
611            key,
612            timestamp.to_le_bytes().as_ref(),
613            SignatureSerialization::Raw,
614        )
615    }
616}
617
618#[cfg(feature = "x255")]
619pub trait X255: CryptoClient {
620    fn generate_x255_secret_key(
621        &mut self,
622        persistence: Location,
623    ) -> ClientResult<'_, reply::GenerateKey, Self> {
624        self.generate_key(
625            Mechanism::X255,
626            StorageAttributes::new().set_persistence(persistence),
627        )
628    }
629
630    fn derive_x255_public_key(
631        &mut self,
632        secret_key: KeyId,
633        persistence: Location,
634    ) -> ClientResult<'_, reply::DeriveKey, Self> {
635        self.derive_key(
636            Mechanism::X255,
637            secret_key,
638            None,
639            StorageAttributes::new().set_persistence(persistence),
640        )
641    }
642
643    fn agree_x255(
644        &mut self,
645        private_key: KeyId,
646        public_key: KeyId,
647        persistence: Location,
648    ) -> ClientResult<'_, reply::Agree, Self> {
649        self.agree(
650            Mechanism::X255,
651            private_key,
652            public_key,
653            StorageAttributes::new().set_persistence(persistence),
654        )
655    }
656}