api_impl/
crypto.rs

1// Copyright 2025 The Fuchsia Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use std::cell::{RefCell, RefMut};
6use std::cmp::min;
7use std::collections::HashMap;
8use std::iter;
9use std::marker::PhantomData;
10use std::rc::Rc;
11
12use aes::{Aes128, Aes192, Aes256};
13use cbc::{Decryptor as CbcDecryptor, Encryptor as CbcEncryptor};
14use cmac::Cmac;
15use crypto_common::{KeyInit, KeyIvInit};
16use digest::DynDigest as Digest;
17use ecb::{Decryptor as EcbDecryptor, Encryptor as EcbEncryptor};
18use hmac::Hmac;
19use rand_core::{CryptoRng, RngCore};
20use rsa::traits::{
21    PaddingScheme as RsaPaddingScheme, PublicKeyParts as _, SignatureScheme as RsaSignatureScheme,
22};
23use rsa::{Oaep, Pss, RsaPrivateKey};
24use sha1::Sha1;
25use sha2::{Sha224, Sha256, Sha384, Sha512};
26use tee_internal::{
27    Algorithm, Attribute, EccCurve, Error, Mode, OperationHandle, Result as TeeResult, Usage,
28};
29
30use crate::ErrorWithSize;
31use crate::storage::{
32    AesKey, HmacSha1Key, HmacSha224Key, HmacSha256Key, HmacSha384Key, HmacSha512Key, Key,
33    KeyType as _, NoKey, Object, RsaKeypair,
34};
35
36type AesCmac128 = Cmac<Aes128>;
37type AesCmac192 = Cmac<Aes192>;
38type AesCmac256 = Cmac<Aes256>;
39type HmacSha1 = Hmac<Sha1>;
40type HmacSha224 = Hmac<Sha224>;
41type HmacSha256 = Hmac<Sha256>;
42type HmacSha384 = Hmac<Sha384>;
43type HmacSha512 = Hmac<Sha512>;
44
45pub fn is_algorithm_supported(alg: Algorithm, element: EccCurve) -> bool {
46    if element != EccCurve::None {
47        return false;
48    }
49    match alg {
50        Algorithm::Sha1
51        | Algorithm::Sha224
52        | Algorithm::Sha256
53        | Algorithm::Sha384
54        | Algorithm::Sha512
55        | Algorithm::AesCbcNopad
56        | Algorithm::AesEcbNopad
57        | Algorithm::AesCmac
58        | Algorithm::HmacSha1
59        | Algorithm::HmacSha224
60        | Algorithm::HmacSha256
61        | Algorithm::HmacSha384
62        | Algorithm::HmacSha512
63        | Algorithm::RsaesPkcs1OaepMgf1Sha1 => true,
64        _ => false,
65    }
66}
67
68// An RNG abstraction in the shape expected by RustCrypto APIs.
69pub(crate) struct Rng {}
70
71impl RngCore for Rng {
72    fn next_u32(&mut self) -> u32 {
73        let val = 0u32;
74        self.fill_bytes(&mut val.to_le_bytes());
75        val
76    }
77
78    fn next_u64(&mut self) -> u64 {
79        let val = 0u64;
80        self.fill_bytes(&mut val.to_le_bytes());
81        val
82    }
83
84    fn fill_bytes(&mut self, dest: &mut [u8]) {
85        zx::cprng_draw(dest)
86    }
87}
88
89impl CryptoRng for Rng {}
90
91// Add a second implementation for `Rng` to satisfy the mismatched dependency
92// version with crypto_common. This can be removed once crypto_common uses
93// rand_core 0.9+.
94impl crypto_common::rand_core::RngCore for Rng {
95    fn next_u32(&mut self) -> u32 {
96        RngCore::next_u32(self)
97    }
98
99    fn next_u64(&mut self) -> u64 {
100        RngCore::next_u64(self)
101    }
102
103    fn fill_bytes(&mut self, dest: &mut [u8]) {
104        RngCore::fill_bytes(self, dest)
105    }
106
107    fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), crypto_common::rand_core::Error> {
108        RngCore::fill_bytes(self, dest);
109        Ok(())
110    }
111}
112
113impl crypto_common::rand_core::CryptoRng for Rng {}
114
115// A MAC abstraction conveniently shaped for our API glue needs.
116trait Mac {
117    fn output_size(&self) -> usize;
118
119    fn update(&mut self, data: &[u8]);
120
121    fn reset(&mut self);
122
123    fn finalize_into_reset(&mut self, out: &mut [u8]);
124
125    // Returns Error::MacInvalid in the case of failure.
126    fn verify_reset(&mut self, expected: &[u8]) -> TeeResult;
127}
128
129// Implementations for the hmac digest types.
130impl<M> Mac for M
131where
132    M: digest::FixedOutputReset + digest::MacMarker + digest::Update,
133{
134    fn output_size(&self) -> usize {
135        // OutputSizeUser is a subtrait of FixedOutputReset.
136        <Self as digest::OutputSizeUser>::output_size()
137    }
138
139    fn update(&mut self, data: &[u8]) {
140        <Self as digest::Update>::update(self, data)
141    }
142
143    fn reset(&mut self) {
144        // Reset is a subtrait of FixedOutputReset.
145        <Self as digest::Reset>::reset(self)
146    }
147
148    fn finalize_into_reset(&mut self, out: &mut [u8]) {
149        <Self as digest::FixedOutputReset>::finalize_into_reset(self, out.into())
150    }
151
152    fn verify_reset(&mut self, expected: &[u8]) -> TeeResult {
153        let finalized = <Self as digest::FixedOutputReset>::finalize_fixed_reset(self);
154        if finalized.as_slice() == expected { Ok(()) } else { Err(Error::MacInvalid) }
155    }
156}
157
158// Supported MAC algorithm types.
159enum MacType {
160    AesCmac,
161    HmacSha1,
162    HmacSha224,
163    HmacSha256,
164    HmacSha384,
165    HmacSha512,
166}
167
168// A cipher abstraction conveniently shaped for our API glue needs.
169trait Cipher {
170    fn block_size(&self) -> usize;
171    fn set_iv(&mut self, iv: &[u8]);
172    fn reset(&mut self);
173    fn encrypt(&self, input: &[u8], output: &mut [u8]);
174    fn encrypt_in_place(&self, inout: &mut [u8]);
175    fn decrypt(&self, input: &[u8], output: &mut [u8]);
176    fn decrypt_in_place(&self, inout: &mut [u8]);
177}
178
179impl<C: PreCipher> Cipher for C {
180    fn set_iv(&mut self, iv: &[u8]) {
181        self.set_iv(iv)
182    }
183
184    fn reset(&mut self) {
185        self.reset()
186    }
187
188    fn block_size(&self) -> usize {
189        debug_assert_eq!(C::Encryptor::block_size(), C::Decryptor::block_size());
190        C::Encryptor::block_size()
191    }
192
193    fn encrypt(&self, input: &[u8], output: &mut [u8]) {
194        self.new_encryptor().encrypt(input, output);
195    }
196
197    fn encrypt_in_place(&self, inout: &mut [u8]) {
198        self.new_encryptor().encrypt_in_place(inout)
199    }
200
201    fn decrypt(&self, input: &[u8], output: &mut [u8]) {
202        self.new_decryptor().decrypt(input, output)
203    }
204
205    fn decrypt_in_place(&self, inout: &mut [u8]) {
206        self.new_decryptor().decrypt_in_place(inout)
207    }
208}
209
210// Ideally, we'd just use a trait like this in place of Cipher, but the
211// presence of associated types makes it non-dyn-compatible.
212trait PreCipher {
213    type Encryptor: Encryptor;
214    type Decryptor: Decryptor;
215
216    fn set_iv(&mut self, iv: &[u8]);
217    fn reset(&mut self);
218
219    // The minting of new encryptors or decryptors in general should happen
220    // only after set_iv() has been called.
221    fn new_encryptor(&self) -> Self::Encryptor;
222    fn new_decryptor(&self) -> Self::Decryptor;
223}
224
225trait Encryptor {
226    fn block_size() -> usize;
227    fn encrypt(&mut self, input: &[u8], output: &mut [u8]);
228    fn encrypt_in_place(&mut self, inout: &mut [u8]);
229}
230
231trait Decryptor {
232    fn block_size() -> usize;
233    fn decrypt(&mut self, input: &[u8], output: &mut [u8]);
234    fn decrypt_in_place(&mut self, inout: &mut [u8]);
235}
236
237// A general cipher type that requires an initialization vector.
238struct CipherWithIv<E, D>
239where
240    E: Encryptor + KeyIvInit,
241    D: Decryptor + KeyIvInit,
242{
243    key: Vec<u8>,
244    iv: Vec<u8>,
245    phantom: PhantomData<(E, D)>,
246}
247
248impl<E, D> CipherWithIv<E, D>
249where
250    E: Encryptor + KeyIvInit,
251    D: Decryptor + KeyIvInit,
252{
253    fn new(key: &[u8]) -> Self {
254        Self { key: key.to_vec(), iv: Vec::new(), phantom: PhantomData::default() }
255    }
256}
257
258impl<E, D> PreCipher for CipherWithIv<E, D>
259where
260    E: Encryptor + KeyIvInit,
261    D: Decryptor + KeyIvInit,
262{
263    type Encryptor = E;
264    type Decryptor = D;
265
266    fn set_iv(&mut self, iv: &[u8]) {
267        self.iv = iv.to_vec()
268    }
269
270    fn reset(&mut self) {
271        self.iv.clear()
272    }
273
274    fn new_encryptor(&self) -> E {
275        E::new_from_slices(&self.key, &self.iv).unwrap()
276    }
277
278    fn new_decryptor(&self) -> D {
279        D::new_from_slices(&self.key, &self.iv).unwrap()
280    }
281}
282
283// A general cipher type that does not require an initialization vector.
284struct CipherWithoutIv<E, D>
285where
286    E: Encryptor + KeyInit,
287    D: Decryptor + KeyInit,
288{
289    key: Vec<u8>,
290    phantom: PhantomData<(E, D)>,
291}
292
293impl<E, D> CipherWithoutIv<E, D>
294where
295    E: Encryptor + KeyInit,
296    D: Decryptor + KeyInit,
297{
298    fn new(key: &[u8]) -> Self {
299        Self { key: key.to_vec(), phantom: PhantomData::default() }
300    }
301}
302
303impl<E, D> PreCipher for CipherWithoutIv<E, D>
304where
305    E: Encryptor + KeyInit,
306    D: Decryptor + KeyInit,
307{
308    type Encryptor = E;
309    type Decryptor = D;
310
311    // Why not panic? Two reasons:
312    // * the spec does not prescribe any behaviour for calling CipherInit(iv)
313    //   for an algorithm that does require an IV, though it does prescribe
314    //   ignoring any IVs passed to MAC algorithms with MacInit(), so there's
315    //   an argument for consistency;
316    // * it simplifies the one intended callsite of CipherInit() to make
317    //   set_iv() and unconditional call.
318    fn set_iv(&mut self, _iv: &[u8]) {}
319
320    fn reset(&mut self) {}
321
322    fn new_encryptor(&self) -> E {
323        E::new_from_slice(&self.key).unwrap()
324    }
325    fn new_decryptor(&self) -> D {
326        D::new_from_slice(&self.key).unwrap()
327    }
328}
329
330// Provides Encryptor and Decryptor implementations for some of the
331// RustCrypto-shaped encryptors and decryptors (which sadly don't implement
332// some official trait themselves encoding their API).
333//
334// We use token trees in the macro matcher to permit the use of `$encryptor<C>`
335// and `$decryptor<C>`, which wouldn't parse if specified more naturally as
336// type paths.
337macro_rules! rustcrypto_encryptor_and_decryptor {
338    ($encryptor:tt, $decryptor:tt) => {
339        impl<C> Encryptor for $encryptor<C>
340        where
341            C: cipher::BlockCipher + cipher::BlockEncryptMut,
342        {
343            fn block_size() -> usize {
344                C::block_size()
345            }
346
347            fn encrypt(&mut self, input: &[u8], output: &mut [u8]) {
348                use cipher::BlockEncryptMut;
349
350                assert!(output.len() >= input.len());
351                let block_size = C::block_size();
352                let chunks =
353                    iter::zip(input.chunks_exact(block_size), output.chunks_exact_mut(block_size));
354                for (in_block, out_block) in chunks {
355                    self.encrypt_block_b2b_mut(in_block.into(), out_block.into());
356                }
357            }
358
359            fn encrypt_in_place(&mut self, inout: &mut [u8]) {
360                use cipher::BlockEncryptMut;
361
362                for block in inout.chunks_exact_mut(C::block_size()) {
363                    self.encrypt_block_mut(block.into())
364                }
365            }
366        }
367
368        impl<C> Decryptor for $decryptor<C>
369        where
370            C: cipher::BlockCipher + cipher::BlockDecryptMut,
371        {
372            fn block_size() -> usize {
373                C::block_size()
374            }
375
376            fn decrypt(&mut self, input: &[u8], output: &mut [u8]) {
377                use cipher::BlockDecryptMut;
378
379                assert!(output.len() >= input.len());
380                let block_size = C::block_size();
381                let chunks =
382                    iter::zip(input.chunks_exact(block_size), output.chunks_exact_mut(block_size));
383                for (in_block, out_block) in chunks {
384                    self.decrypt_block_b2b_mut(in_block.into(), out_block.into());
385                }
386            }
387
388            fn decrypt_in_place(&mut self, inout: &mut [u8]) {
389                use cipher::BlockDecryptMut;
390
391                for block in inout.chunks_exact_mut(C::block_size()) {
392                    self.decrypt_block_mut(block.into())
393                }
394            }
395        }
396    };
397}
398
399rustcrypto_encryptor_and_decryptor!(CbcEncryptor, CbcDecryptor);
400rustcrypto_encryptor_and_decryptor!(EcbEncryptor, EcbDecryptor);
401
402type AesCbcNopad<C> = CipherWithIv<cbc::Encryptor<C>, cbc::Decryptor<C>>;
403type Aes128CbcNopad = AesCbcNopad<Aes128>;
404type Aes192CbcNopad = AesCbcNopad<Aes192>;
405type Aes256CbcNopad = AesCbcNopad<Aes256>;
406
407type AesEcbNopad<C> = CipherWithoutIv<ecb::Encryptor<C>, ecb::Decryptor<C>>;
408type Aes128EcbNopad = AesEcbNopad<Aes128>;
409type Aes192EcbNopad = AesEcbNopad<Aes192>;
410type Aes256EcbNopad = AesEcbNopad<Aes256>;
411
412enum CipherType {
413    AesCbcNopad,
414    AesEcbNopad,
415}
416
417trait AsymmetricEncryptionKey {
418    fn decrypt(
419        &self,
420        params: &[Attribute],
421        input: &[u8],
422        output: &mut [u8],
423    ) -> Result<usize, ErrorWithSize>;
424}
425
426trait RsaPadding<D>: RsaPaddingScheme
427where
428    D: 'static + Digest + digest::Digest + Send + Sync,
429{
430    fn new() -> Self;
431}
432
433impl<D> RsaPadding<D> for Oaep
434where
435    D: 'static + Digest + digest::Digest + Send + Sync,
436{
437    fn new() -> Self {
438        Oaep::new::<D>()
439    }
440}
441
442struct RsaEncryptionKey<D, Padding>
443where
444    D: 'static + Digest + digest::Digest + Send + Sync,
445    Padding: RsaPadding<D>,
446{
447    private: Rc<RsaPrivateKey>,
448    phantom: PhantomData<(D, Padding)>,
449}
450
451impl<D, Padding> RsaEncryptionKey<D, Padding>
452where
453    D: 'static + Digest + digest::Digest + Send + Sync,
454    Padding: RsaPadding<D>,
455{
456    fn new(private: Rc<RsaPrivateKey>) -> Self {
457        Self { private, phantom: PhantomData::default() }
458    }
459}
460
461impl<D, Padding> AsymmetricEncryptionKey for RsaEncryptionKey<D, Padding>
462where
463    D: 'static + Digest + digest::Digest + Send + Sync,
464    Padding: RsaPadding<D>,
465{
466    fn decrypt(
467        &self,
468        params: &[Attribute],
469        input: &[u8],
470        output: &mut [u8],
471    ) -> Result<usize, ErrorWithSize> {
472        if !params.is_empty() {
473            unimplemented!();
474        }
475        let output_size = self.private.size() as usize;
476        if input.len() != output_size {
477            return Err(ErrorWithSize::new(Error::BadParameters));
478        }
479        if output.len() < output_size {
480            return Err(ErrorWithSize::short_buffer(output_size));
481        }
482
483        let decrypted = self.private.decrypt(Padding::new(), input).expect("Failed to decrypt");
484        let written = &mut output[..decrypted.len()];
485        written.copy_from_slice(&decrypted);
486        Ok(written.len())
487    }
488}
489
490enum AsymmetricEncryptionKeyType {
491    RsaOaepSha1,
492}
493
494trait AsymmetricSigningKey {
495    fn sign(
496        &self,
497        params: &[Attribute],
498        input: &[u8],
499        output: &mut [u8],
500    ) -> Result<usize, ErrorWithSize>;
501}
502
503trait RsaSignature<D>: RsaSignatureScheme
504where
505    D: 'static + Digest + digest::Digest + Send + Sync,
506{
507    fn new() -> Self;
508}
509
510impl<D> RsaSignature<D> for Pss
511where
512    D: 'static + Digest + digest::Digest + Send + Sync,
513{
514    fn new() -> Self {
515        Pss::new::<D>()
516    }
517}
518
519struct RsaSigningKey<D, Signature>
520where
521    D: 'static + Digest + digest::Digest + Send + Sync,
522    Signature: RsaSignature<D>,
523{
524    private: Rc<RsaPrivateKey>,
525    phantom: PhantomData<(D, Signature)>,
526}
527
528impl<D, Signature> RsaSigningKey<D, Signature>
529where
530    D: 'static + Digest + digest::Digest + Send + Sync,
531    Signature: RsaSignature<D>,
532{
533    fn new(private: Rc<RsaPrivateKey>) -> Self {
534        Self { private, phantom: PhantomData::default() }
535    }
536}
537
538impl<D, Signature> AsymmetricSigningKey for RsaSigningKey<D, Signature>
539where
540    D: 'static + Digest + digest::Digest + Send + Sync,
541    Signature: RsaSignature<D>,
542{
543    fn sign(
544        &self,
545        params: &[Attribute],
546        input: &[u8],
547        output: &mut [u8],
548    ) -> Result<usize, ErrorWithSize> {
549        assert!(params.is_empty());
550        let output_size = self.private.size() as usize;
551        if output.len() < output_size {
552            return Err(ErrorWithSize::short_buffer(output_size));
553        }
554
555        let signed = self
556            .private
557            .sign_with_rng(&mut Rng {}, Signature::new(), input)
558            .expect("Failed to sign");
559        let written = &mut output[..signed.len()];
560        written.copy_from_slice(&signed);
561        Ok(written.len())
562    }
563}
564
565enum AsymmetricSigningKeyType {
566    RsaPssSha1,
567}
568
569// Encapsulated an abstracted helper classes particular to supported
570// algorithms.
571enum Helper {
572    Digest(Box<dyn Digest>),
573    Cipher(Option<Box<dyn Cipher>>, CipherType),
574    Mac(Option<Box<dyn Mac>>, MacType),
575    AsymmetricEncryptionKey(Option<Box<dyn AsymmetricEncryptionKey>>, AsymmetricEncryptionKeyType),
576    AsymmetricSigningKey(Option<Box<dyn AsymmetricSigningKey>>, AsymmetricSigningKeyType),
577}
578
579impl Helper {
580    fn new(algorithm: Algorithm) -> TeeResult<Self> {
581        match algorithm {
582            Algorithm::Sha1 => Ok(Helper::Digest(Box::new(Sha1::default()))),
583            Algorithm::Sha224 => Ok(Helper::Digest(Box::new(Sha224::default()))),
584            Algorithm::Sha256 => Ok(Helper::Digest(Box::new(Sha256::default()))),
585            Algorithm::Sha384 => Ok(Helper::Digest(Box::new(Sha384::default()))),
586            Algorithm::Sha512 => Ok(Helper::Digest(Box::new(Sha512::default()))),
587            Algorithm::AesCbcNopad => Ok(Helper::Cipher(None, CipherType::AesCbcNopad)),
588            Algorithm::AesEcbNopad => Ok(Helper::Cipher(None, CipherType::AesEcbNopad)),
589            Algorithm::AesCmac => Ok(Helper::Mac(None, MacType::AesCmac)),
590            Algorithm::HmacSha1 => Ok(Helper::Mac(None, MacType::HmacSha1)),
591            Algorithm::HmacSha224 => Ok(Helper::Mac(None, MacType::HmacSha224)),
592            Algorithm::HmacSha256 => Ok(Helper::Mac(None, MacType::HmacSha256)),
593            Algorithm::HmacSha384 => Ok(Helper::Mac(None, MacType::HmacSha384)),
594            Algorithm::HmacSha512 => Ok(Helper::Mac(None, MacType::HmacSha512)),
595            Algorithm::RsaesPkcs1OaepMgf1Sha1 => {
596                Ok(Helper::AsymmetricEncryptionKey(None, AsymmetricEncryptionKeyType::RsaOaepSha1))
597            }
598            Algorithm::RsassaPkcs1PssMgf1Sha1 => {
599                Ok(Helper::AsymmetricSigningKey(None, AsymmetricSigningKeyType::RsaPssSha1))
600            }
601            _ => Err(Error::NotSupported),
602        }
603    }
604
605    fn initialize(&mut self, key: &Key) {
606        match self {
607            Helper::Digest(digest) => {
608                // Digests do not need initialization.
609                assert!(matches!(key, Key::Data(NoKey {})));
610                digest.reset()
611            }
612            Helper::Cipher(cipher, cipher_type) => {
613                let Key::Aes(AesKey { secret }) = key else {
614                    panic!("Wrong key type ({:?}) - expected AES", key.get_type());
615                };
616
617                match cipher_type {
618                    CipherType::AesCbcNopad => {
619                        let cbc: Box<dyn Cipher> = match secret.len() {
620                            16 => Box::new(Aes128CbcNopad::new(&secret)),
621                            24 => Box::new(Aes192CbcNopad::new(&secret)),
622                            32 => Box::new(Aes256CbcNopad::new(&secret)),
623                            len => panic!("Invalid AES key length: {len}"),
624                        };
625                        *cipher = Some(cbc);
626                    }
627                    CipherType::AesEcbNopad => {
628                        let ecb: Box<dyn Cipher> = match secret.len() {
629                            16 => Box::new(Aes128EcbNopad::new(&secret)),
630                            24 => Box::new(Aes192EcbNopad::new(&secret)),
631                            32 => Box::new(Aes256EcbNopad::new(&secret)),
632                            len => panic!("Invalid AES key length: {len}"),
633                        };
634                        *cipher = Some(ecb);
635                    }
636                }
637            }
638            Helper::Mac(mac, mac_type) => match mac_type {
639                MacType::AesCmac => {
640                    let Key::Aes(AesKey { secret }) = key else {
641                        panic!("Wrong key type ({:?}) - expected AES", key.get_type());
642                    };
643                    let cmac: Box<dyn Mac> = match secret.len() {
644                        16 => Box::new(AesCmac128::new_from_slice(&secret).unwrap()),
645                        24 => Box::new(AesCmac192::new_from_slice(&secret).unwrap()),
646                        32 => Box::new(AesCmac256::new_from_slice(&secret).unwrap()),
647                        len => panic!("Invalid AES key length: {len}"),
648                    };
649                    *mac = Some(cmac);
650                }
651                MacType::HmacSha1 => {
652                    let Key::HmacSha1(HmacSha1Key { secret }) = key else {
653                        panic!("Wrong key type ({:?}) - expected HMAC SHA1", key.get_type());
654                    };
655                    *mac = Some(Box::new(HmacSha1::new_from_slice(&secret).unwrap()))
656                }
657                MacType::HmacSha224 => {
658                    let Key::HmacSha224(HmacSha224Key { secret }) = key else {
659                        panic!("Wrong key type ({:?}) - expected HMAC SHA224", key.get_type());
660                    };
661                    *mac = Some(Box::new(HmacSha224::new_from_slice(&secret).unwrap()))
662                }
663                MacType::HmacSha256 => {
664                    let Key::HmacSha256(HmacSha256Key { secret }) = key else {
665                        panic!("Wrong key type ({:?}) - expected HMAC SHA256", key.get_type());
666                    };
667                    *mac = Some(Box::new(HmacSha256::new_from_slice(&secret).unwrap()))
668                }
669                MacType::HmacSha384 => {
670                    let Key::HmacSha384(HmacSha384Key { secret }) = key else {
671                        panic!("Wrong key type ({:?}) - expected HMAC SHA384", key.get_type());
672                    };
673                    *mac = Some(Box::new(HmacSha384::new_from_slice(&secret).unwrap()))
674                }
675                MacType::HmacSha512 => {
676                    let Key::HmacSha512(HmacSha512Key { secret }) = key else {
677                        panic!("Wrong key type ({:?}) - expected HMAC SHA512", key.get_type());
678                    };
679                    *mac = Some(Box::new(HmacSha512::new_from_slice(&secret).unwrap()))
680                }
681            },
682            Helper::AsymmetricEncryptionKey(aenc, aenc_type) => match aenc_type {
683                AsymmetricEncryptionKeyType::RsaOaepSha1 => {
684                    let Key::RsaKeypair(rsa) = key else {
685                        panic!("Wrong key type ({:?}) - expected RSA keypair", key.get_type());
686                    };
687                    *aenc = Some(Box::new(RsaEncryptionKey::<Sha1, Oaep>::new(rsa.private_key())));
688                }
689            },
690            Helper::AsymmetricSigningKey(asign, asign_type) => match asign_type {
691                AsymmetricSigningKeyType::RsaPssSha1 => {
692                    let Key::RsaKeypair(rsa) = key else {
693                        panic!("Wrong key type ({:?}) - expected RSA keypair", key.get_type());
694                    };
695                    *asign = Some(Box::new(RsaSigningKey::<Sha1, Pss>::new(rsa.private_key())));
696                }
697            },
698        }
699    }
700
701    fn reset(&mut self) {
702        match self {
703            Helper::Digest(digest) => digest.reset(),
704            Helper::Cipher(cipher, _) => {
705                if let Some(cipher) = cipher {
706                    cipher.reset()
707                }
708            }
709            Helper::Mac(mac, _) => {
710                if let Some(mac) = mac {
711                    mac.reset()
712                }
713            }
714            Helper::AsymmetricEncryptionKey(_, _) => {}
715            Helper::AsymmetricSigningKey(_, _) => {}
716        }
717    }
718}
719
720#[derive(Debug, Eq, PartialEq)]
721enum OpState {
722    Initial,
723    Active,
724    // Holds the finalized data yet to be fully extracted, along with an index
725    // pointing to the next byte to extract.
726    Extracting((Vec<u8>, usize)),
727}
728
729pub struct Operation {
730    algorithm: Algorithm,
731    mode: Mode,
732    key: Key,
733    max_key_size: u32, // The initial, allocated max key size.
734    state: OpState,
735    helper: Helper,
736}
737
738impl Operation {
739    fn new(algorithm: Algorithm, mode: Mode, max_key_size: u32) -> TeeResult<Self> {
740        Ok(Self {
741            algorithm,
742            mode,
743            key: Key::Data(NoKey {}),
744            max_key_size,
745            state: OpState::Initial,
746            helper: Helper::new(algorithm)?,
747        })
748    }
749
750    fn as_digest(&mut self) -> &mut Box<dyn Digest> {
751        if let Helper::Digest(digest) = &mut self.helper {
752            digest
753        } else {
754            panic!("{:?} is not a digest algorithm", self.algorithm)
755        }
756    }
757
758    fn as_cipher(&mut self) -> &mut Box<dyn Cipher> {
759        if let Helper::Cipher(cipher, _) = &mut self.helper {
760            cipher.as_mut().expect("TEE_OperationSetKey() has not yet been called")
761        } else {
762            panic!("{:?} is not a cipher algorithm", self.algorithm)
763        }
764    }
765
766    fn as_mac(&mut self) -> &mut Box<dyn Mac> {
767        if let Helper::Mac(mac, _) = &mut self.helper {
768            mac.as_mut().expect("TEE_OperationSetKey() has not yet been called")
769        } else {
770            panic!("{:?} is not a MAC algorithm", self.algorithm)
771        }
772    }
773
774    fn as_asymmetric_encryption_key(&mut self) -> &mut Box<dyn AsymmetricEncryptionKey> {
775        if let Helper::AsymmetricEncryptionKey(aenc, _) = &mut self.helper {
776            aenc.as_mut().expect("TEE_OperationSetKey() has not yet been called")
777        } else {
778            panic!("{:?} is not a asymmetric encryption key algorithm", self.algorithm)
779        }
780    }
781
782    fn as_asymmetric_signing_key(&mut self) -> &mut Box<dyn AsymmetricSigningKey> {
783        if let Helper::AsymmetricSigningKey(aenc, _) = &mut self.helper {
784            aenc.as_mut().expect("TEE_OperationSetKey() has not yet been called")
785        } else {
786            panic!("{:?} is not a asymmetric signing key algorithm", self.algorithm)
787        }
788    }
789
790    // Returns whether the operation is in the extracting state and, if so, the
791    // number of remaining bytes left to extract.
792    fn is_extracting(&self) -> (bool, usize) {
793        if let OpState::Extracting((ref data, ref pos)) = self.state {
794            (true, data.len() - pos)
795        } else {
796            (false, 0)
797        }
798    }
799
800    fn reset(&mut self) {
801        self.helper.reset();
802        self.state = OpState::Initial;
803    }
804
805    fn set_key(&mut self, obj: Rc<RefCell<dyn Object>>) -> TeeResult {
806        let obj = obj.borrow();
807        let key = obj.key();
808
809        assert!(
810            key.max_size() <= self.max_key_size,
811            "Provided key size ({}) exceeds configured max ({})",
812            key.max_size(),
813            self.max_key_size
814        );
815
816        assert_eq!(
817            self.state,
818            OpState::Initial,
819            "Operation must be in the initial state (not {:?})",
820            self.state
821        );
822
823        match self.algorithm {
824            Algorithm::AesCbcNopad | Algorithm::AesEcbNopad => match self.mode {
825                Mode::Encrypt | Mode::Decrypt => {
826                    let usage = obj.usage();
827                    if self.mode == Mode::Encrypt {
828                        assert!(usage.contains(Usage::ENCRYPT | Usage::VERIFY));
829                    } else {
830                        assert!(usage.contains(Usage::DECRYPT | Usage::SIGN));
831                    }
832                }
833                _ => return Err(Error::NotImplemented),
834            },
835            Algorithm::Md5
836            | Algorithm::Sha1
837            | Algorithm::Sha224
838            | Algorithm::Sha256
839            | Algorithm::Sha384
840            | Algorithm::Sha512
841            | Algorithm::Sha3_224
842            | Algorithm::Sha3_256
843            | Algorithm::Sha3_384
844            | Algorithm::Sha3_512
845            | Algorithm::Shake128
846            | Algorithm::Shake256 => {
847                panic!("Algorithm {:?} has no associated object type", self.algorithm);
848            }
849            Algorithm::AesCmac
850            | Algorithm::HmacSha1
851            | Algorithm::HmacSha224
852            | Algorithm::HmacSha256
853            | Algorithm::HmacSha384
854            | Algorithm::HmacSha512 => {}
855            Algorithm::RsaesPkcs1OaepMgf1Sha1 => {}
856            Algorithm::RsassaPkcs1PssMgf1Sha1 => {}
857            _ => return Err(Error::NotImplemented),
858        };
859        self.key = key.clone();
860        self.helper.initialize(&self.key);
861        Ok(())
862    }
863
864    fn clear_key(&mut self) -> TeeResult {
865        self.key = Key::Data(NoKey {});
866        self.state = OpState::Initial;
867        Ok(())
868    }
869
870    // Provided the operation is in its extracting state, this reads as many
871    // bytes of that data as possible into the provided buffer, returning the
872    // size of the read.
873    fn extract_finalized(&mut self, buf: &mut [u8]) -> usize {
874        let OpState::Extracting((ref data, ref mut pos)) = self.state else {
875            panic!("Operation is not in the extracting state: {:?}", self.state);
876        };
877        if buf.is_empty() || *pos >= data.len() {
878            return 0;
879        }
880        let read_size = min(data.len() - *pos, buf.len());
881        let in_chunk = &data.as_slice()[*pos..(*pos + read_size)];
882        let out_chunk = &mut buf[..read_size];
883        out_chunk.copy_from_slice(in_chunk);
884        *pos += read_size;
885        read_size
886    }
887
888    // See TEE_DigestUpdate().
889    fn update_digest(&mut self, chunk: &[u8]) {
890        assert_eq!(self.mode, Mode::Digest);
891        assert!(self.state == OpState::Initial || self.state == OpState::Active);
892        self.as_digest().update(chunk);
893        self.state = OpState::Active;
894    }
895
896    // See TEE_DigestDoFinal().
897    //
898    // This should be two separate operations each with clean semantics:
899    // update + finalize. However, the spec wants the two zipped together here
900    // where the first can't happen if the preconditions of the second aren't
901    // met, adding complication.
902    fn update_and_finalize_digest_into(
903        &mut self,
904        last_chunk: &[u8],
905        buf: &mut [u8],
906    ) -> Result<(), ErrorWithSize> {
907        assert_eq!(self.mode, Mode::Digest);
908
909        if let (true, left_to_extract) = self.is_extracting() {
910            assert!(last_chunk.is_empty());
911
912            if left_to_extract > buf.len() {
913                return Err(ErrorWithSize::short_buffer(left_to_extract));
914            }
915
916            let written = self.extract_digest(buf);
917            debug_assert_eq!(written, left_to_extract);
918            self.state = OpState::Initial;
919            return Ok(());
920        }
921
922        let buf = {
923            let digest = self.as_digest();
924            let output_size = digest.output_size();
925            if output_size > buf.len() {
926                return Err(ErrorWithSize::short_buffer(output_size));
927            }
928
929            if !last_chunk.is_empty() {
930                digest.update(last_chunk);
931            }
932            &mut buf[..output_size]
933        };
934
935        self.as_digest().finalize_into_reset(buf).unwrap();
936        self.state = OpState::Initial;
937        Ok(())
938    }
939
940    // Finalizes the digest and puts the operation in the extracting state. If
941    // already in the extracting state, this is a no-op.
942    fn finalize_digest(&mut self) {
943        assert_eq!(self.mode, Mode::Digest);
944        let (extracting, _) = self.is_extracting();
945        if extracting {
946            return;
947        }
948
949        let bytes = self.as_digest().finalize_reset();
950        self.state = OpState::Extracting((Vec::from(bytes), 0));
951    }
952
953    // See TEE_DigestExtract().
954    fn extract_digest(&mut self, buf: &mut [u8]) -> usize {
955        self.finalize_digest();
956        self.extract_finalized(buf)
957    }
958
959    // See TEE_CipherInit()
960    fn init_cipher(&mut self, iv: &[u8]) {
961        if self.state == OpState::Active {
962            self.as_cipher().reset();
963        } else {
964            assert_eq!(self.state, OpState::Initial);
965        }
966
967        self.as_cipher().set_iv(iv);
968
969        // Currently supported MAC algorithms don't deal in initialization vectors.
970        self.state = OpState::Active;
971    }
972
973    // The error value indicates the minimum required size of the output buffer
974    // (i.e., the total number of full blocks to encrypt/decrypt).
975    fn update_cipher(&mut self, src: &[u8], dest: &mut [u8]) -> Result<(), ErrorWithSize> {
976        assert_eq!(self.state, OpState::Active);
977
978        let block_size = self.as_cipher().block_size();
979        let num_blocks_in = src.len() / block_size;
980        let num_blocks_out = dest.len() / block_size;
981
982        // The output buffer size should be at least the total size of the
983        // number of full blocks in `src` to encrypt/decrypt.
984        if num_blocks_in > num_blocks_out {
985            return Err(ErrorWithSize::short_buffer(num_blocks_in * block_size));
986        }
987
988        if self.mode == Mode::Encrypt {
989            self.as_cipher().encrypt(src, dest);
990        } else {
991            assert_eq!(self.mode, Mode::Decrypt);
992            self.as_cipher().decrypt(src, dest);
993        }
994        Ok(())
995    }
996
997    fn update_cipher_in_place(&mut self, inout: &mut [u8]) {
998        assert_eq!(self.state, OpState::Active);
999
1000        if self.mode == Mode::Encrypt {
1001            self.as_cipher().encrypt_in_place(inout);
1002        } else {
1003            assert_eq!(self.mode, Mode::Decrypt);
1004            self.as_cipher().decrypt_in_place(inout);
1005        }
1006    }
1007
1008    // The error value indicates the minimum required size of the output buffer
1009    // (i.e., the total number of full blocks to encrypt/decrypt, which should
1010    // be the same size as `src` itself).
1011    fn finalize_cipher(&mut self, src: &[u8], dest: &mut [u8]) -> Result<(), ErrorWithSize> {
1012        let block_size = self.as_cipher().block_size();
1013        assert_eq!(src.len() % block_size, 0);
1014        assert!(dest.len() >= src.len());
1015        self.update_cipher(src, dest)?;
1016        self.state = OpState::Initial;
1017        Ok(())
1018    }
1019
1020    fn finalize_cipher_in_place(&mut self, inout: &mut [u8]) {
1021        let block_size = self.as_cipher().block_size();
1022        assert_eq!(inout.len() % block_size, 0);
1023        self.update_cipher_in_place(inout);
1024        self.state = OpState::Initial;
1025    }
1026
1027    // See TEE_MACInit().
1028    fn init_mac(&mut self, _iv: &[u8]) {
1029        assert_eq!(self.mode, Mode::Mac);
1030        assert!(self.state == OpState::Initial || self.state == OpState::Active);
1031
1032        if self.state == OpState::Active {
1033            self.as_mac().reset();
1034        }
1035
1036        // Currently supported MAC algorithms don't deal in initialization
1037        // vectors; the spec say to ignore the provided one in that case.
1038
1039        self.state = OpState::Active;
1040    }
1041
1042    // See TEE_MACUpdate().
1043    fn update_mac(&mut self, chunk: &[u8]) {
1044        assert_eq!(self.mode, Mode::Mac);
1045        assert_eq!(self.state, OpState::Active);
1046
1047        let mac = self.as_mac();
1048        if !chunk.is_empty() {
1049            mac.update(chunk);
1050        }
1051    }
1052
1053    // See TEE_MACComputeFinal().
1054    fn compute_final_mac(
1055        &mut self,
1056        message: &[u8],
1057        output: &mut [u8],
1058    ) -> Result<(), ErrorWithSize> {
1059        assert_eq!(self.mode, Mode::Mac);
1060        assert_eq!(self.state, OpState::Active);
1061
1062        let output_size = self.as_mac().output_size();
1063        if output.len() < output_size {
1064            return Err(ErrorWithSize::short_buffer(output_size));
1065        }
1066
1067        // Make sure we validate the output buffer size before updating the
1068        // digest.
1069        let mac = self.as_mac();
1070        if !message.is_empty() {
1071            mac.update(message);
1072        }
1073        mac.finalize_into_reset(&mut output[..output_size]);
1074        self.state = OpState::Initial;
1075        Ok(())
1076    }
1077
1078    // See TEE_MACCompareFinal().
1079    fn compare_final_mac(&mut self, message: &[u8], expected: &[u8]) -> TeeResult {
1080        self.update_mac(message);
1081        let result = self.as_mac().verify_reset(expected);
1082        self.state = OpState::Initial;
1083        result
1084    }
1085
1086    // See TEE_AsymmetricDecrypt().
1087    fn asymmetric_decrypt(
1088        &mut self,
1089        params: &[Attribute],
1090        src: &[u8],
1091        dest: &mut [u8],
1092    ) -> Result<usize, ErrorWithSize> {
1093        assert_eq!(self.mode, Mode::Decrypt);
1094        self.as_asymmetric_encryption_key().decrypt(params, src, dest)
1095    }
1096
1097    // See TEE_AsymmetricSignDigest().
1098    fn asymmetric_sign_digest(
1099        &mut self,
1100        params: &[Attribute],
1101        digest: &[u8],
1102        signature: &mut [u8],
1103    ) -> Result<usize, ErrorWithSize> {
1104        assert_eq!(self.mode, Mode::Sign);
1105        self.as_asymmetric_signing_key().sign(params, digest, signature)
1106    }
1107}
1108
1109pub struct Operations {
1110    operations: HashMap<OperationHandle, RefCell<Operation>>,
1111    next_operation_handle_value: OperationHandle,
1112}
1113
1114impl Operations {
1115    pub fn new() -> Self {
1116        Self {
1117            operations: HashMap::new(),
1118            next_operation_handle_value: OperationHandle::from_value(1),
1119        }
1120    }
1121
1122    pub fn allocate(
1123        &mut self,
1124        algorithm: Algorithm,
1125        mode: Mode,
1126        max_key_size: u32,
1127    ) -> TeeResult<OperationHandle> {
1128        // We could directly check `FooKey::is_valid_size(max_key_size)` in
1129        // each match arm, but by forwarding the appropriate key size check
1130        // function pointer and doing it indirectly after the match statement,
1131        // we ensure that the check is always made and reduce a bit of
1132        // boilerplate while we're at it.
1133        let is_valid_key_size = match algorithm {
1134            Algorithm::AesCbcNopad | Algorithm::AesEcbNopad => {
1135                match mode {
1136                    Mode::Encrypt | Mode::Decrypt => {}
1137                    _ => {
1138                        return Err(Error::NotSupported);
1139                    }
1140                };
1141                AesKey::is_valid_size
1142            }
1143            Algorithm::Md5
1144            | Algorithm::Sha1
1145            | Algorithm::Sha224
1146            | Algorithm::Sha256
1147            | Algorithm::Sha384
1148            | Algorithm::Sha512
1149            | Algorithm::Sha3_224
1150            | Algorithm::Sha3_256
1151            | Algorithm::Sha3_384
1152            | Algorithm::Sha3_512
1153            | Algorithm::Shake128
1154            | Algorithm::Shake256 => {
1155                if mode != Mode::Digest {
1156                    return Err(Error::NotSupported);
1157                }
1158                NoKey::is_valid_size
1159            }
1160            Algorithm::AesCmac => {
1161                if mode != Mode::Mac {
1162                    return Err(Error::NotSupported);
1163                }
1164                AesKey::is_valid_size
1165            }
1166            Algorithm::HmacSha1 => {
1167                if mode != Mode::Mac {
1168                    return Err(Error::NotSupported);
1169                }
1170                HmacSha1Key::is_valid_size
1171            }
1172            Algorithm::HmacSha224 => {
1173                if mode != Mode::Mac {
1174                    return Err(Error::NotSupported);
1175                }
1176                HmacSha224Key::is_valid_size
1177            }
1178            Algorithm::HmacSha256 => {
1179                if mode != Mode::Mac {
1180                    return Err(Error::NotSupported);
1181                }
1182                HmacSha256Key::is_valid_size
1183            }
1184            Algorithm::HmacSha384 => {
1185                if mode != Mode::Mac {
1186                    return Err(Error::NotSupported);
1187                }
1188                HmacSha384Key::is_valid_size
1189            }
1190            Algorithm::HmacSha512 => {
1191                if mode != Mode::Mac {
1192                    return Err(Error::NotSupported);
1193                }
1194                HmacSha512Key::is_valid_size
1195            }
1196            Algorithm::RsaesPkcs1OaepMgf1Sha1 => {
1197                if mode != Mode::Encrypt && mode != Mode::Decrypt {
1198                    return Err(Error::NotSupported);
1199                }
1200                RsaKeypair::is_valid_size
1201            }
1202            Algorithm::RsassaPkcs1PssMgf1Sha1 => {
1203                if mode != Mode::Sign && mode != Mode::Verify {
1204                    return Err(Error::NotSupported);
1205                }
1206                RsaKeypair::is_valid_size
1207            }
1208            _ => {
1209                inspect_stubs::track_stub!(
1210                    TODO("https://fxbug.dev/360942581"),
1211                    "unsupported algorithm",
1212                );
1213                return Err(Error::NotImplemented);
1214            }
1215        };
1216        if !is_valid_key_size(max_key_size) {
1217            return Err(Error::NotSupported);
1218        }
1219        let operation = Operation::new(algorithm, mode, max_key_size)?;
1220        let handle = self.allocate_operation_handle();
1221        let prev = self.operations.insert(handle, RefCell::new(operation));
1222        debug_assert!(prev.is_none());
1223        Ok(handle)
1224    }
1225
1226    fn allocate_operation_handle(&mut self) -> OperationHandle {
1227        let handle = self.next_operation_handle_value;
1228        self.next_operation_handle_value = OperationHandle::from_value(*handle + 1);
1229        handle
1230    }
1231
1232    fn get_mut(&self, operation: OperationHandle) -> RefMut<'_, Operation> {
1233        self.operations.get(&operation).unwrap().borrow_mut()
1234    }
1235
1236    pub fn free(&mut self, operation: OperationHandle) {
1237        if operation.is_null() {
1238            return;
1239        }
1240        let _ = self.operations.remove(&operation).unwrap();
1241    }
1242
1243    pub fn reset(&mut self, operation: OperationHandle) {
1244        self.get_mut(operation).reset()
1245    }
1246
1247    pub fn set_key(
1248        &mut self,
1249        operation: OperationHandle,
1250        key: Rc<RefCell<dyn Object>>,
1251    ) -> TeeResult {
1252        self.get_mut(operation).set_key(key)
1253    }
1254
1255    pub fn clear_key(&mut self, operation: OperationHandle) -> TeeResult {
1256        self.get_mut(operation).clear_key()
1257    }
1258
1259    pub fn update_digest(&mut self, operation: OperationHandle, chunk: &[u8]) {
1260        self.get_mut(operation).update_digest(chunk);
1261    }
1262
1263    pub fn update_and_finalize_digest_into(
1264        &mut self,
1265        operation: OperationHandle,
1266        last_chunk: &[u8],
1267        buf: &mut [u8],
1268    ) -> Result<(), ErrorWithSize> {
1269        self.get_mut(operation).update_and_finalize_digest_into(last_chunk, buf)
1270    }
1271
1272    pub fn extract_digest<'a>(&mut self, operation: OperationHandle, buf: &'a mut [u8]) -> usize {
1273        self.get_mut(operation).extract_digest(buf)
1274    }
1275
1276    pub fn init_cipher(&mut self, operation: OperationHandle, iv: &[u8]) {
1277        self.get_mut(operation).init_cipher(iv)
1278    }
1279
1280    pub fn update_cipher(
1281        &mut self,
1282        operation: OperationHandle,
1283        input: &[u8],
1284        output: &mut [u8],
1285    ) -> Result<(), ErrorWithSize> {
1286        self.get_mut(operation).update_cipher(input, output)
1287    }
1288
1289    pub fn update_cipher_in_place(&mut self, operation: OperationHandle, inout: &mut [u8]) {
1290        self.get_mut(operation).update_cipher_in_place(inout)
1291    }
1292
1293    pub fn finalize_cipher(
1294        &mut self,
1295        operation: OperationHandle,
1296        input: &[u8],
1297        output: &mut [u8],
1298    ) -> Result<(), ErrorWithSize> {
1299        self.get_mut(operation).finalize_cipher(input, output)
1300    }
1301
1302    pub fn finalize_cipher_in_place(&mut self, operation: OperationHandle, inout: &mut [u8]) {
1303        self.get_mut(operation).finalize_cipher_in_place(inout)
1304    }
1305
1306    pub fn init_mac(&mut self, operation: OperationHandle, iv: &[u8]) {
1307        self.get_mut(operation).init_mac(iv)
1308    }
1309
1310    pub fn update_mac(&mut self, operation: OperationHandle, chunk: &[u8]) {
1311        self.get_mut(operation).update_mac(chunk)
1312    }
1313
1314    pub fn compute_final_mac(
1315        &mut self,
1316        operation: OperationHandle,
1317        message: &[u8],
1318        mac: &mut [u8],
1319    ) -> Result<(), ErrorWithSize> {
1320        self.get_mut(operation).compute_final_mac(message, mac)
1321    }
1322
1323    pub fn compare_final_mac(
1324        &mut self,
1325        operation: OperationHandle,
1326        message: &[u8],
1327        mac: &[u8],
1328    ) -> TeeResult {
1329        self.get_mut(operation).compare_final_mac(message, mac)
1330    }
1331
1332    pub fn asymmetric_decrypt(
1333        &mut self,
1334        operation: OperationHandle,
1335        params: &[Attribute],
1336        src: &[u8],
1337        dest: &mut [u8],
1338    ) -> Result<usize, ErrorWithSize> {
1339        self.get_mut(operation).asymmetric_decrypt(params, src, dest)
1340    }
1341
1342    pub fn asymmetric_sign_digest(
1343        &mut self,
1344        operation: OperationHandle,
1345        params: &[Attribute],
1346        digest: &[u8],
1347        signature: &mut [u8],
1348    ) -> Result<usize, ErrorWithSize> {
1349        self.get_mut(operation).asymmetric_sign_digest(params, digest, signature)
1350    }
1351}
1352
1353#[cfg(test)]
1354mod tests {
1355    use super::*;
1356
1357    #[fuchsia::test]
1358    fn operation_lifecycle() -> Result<(), Error> {
1359        let mut operations = Operations::new();
1360
1361        let operation = operations.allocate(Algorithm::Sha256, Mode::Digest, 0).unwrap();
1362
1363        operations.free(operation);
1364
1365        Ok(())
1366    }
1367}