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