1use 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
68pub(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
91impl 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
115trait 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 fn verify_reset(&mut self, expected: &[u8]) -> TeeResult;
127}
128
129impl<M> Mac for M
131where
132 M: digest::FixedOutputReset + digest::MacMarker + digest::Update,
133{
134 fn output_size(&self) -> usize {
135 <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 <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
158enum MacType {
160 AesCmac,
161 HmacSha1,
162 HmacSha224,
163 HmacSha256,
164 HmacSha384,
165 HmacSha512,
166}
167
168trait 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
210trait 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 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
237struct 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
283struct 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 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
330macro_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
569enum 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 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 Extracting((Vec<u8>, usize)),
727}
728
729pub struct Operation {
730 algorithm: Algorithm,
731 mode: Mode,
732 key: Key,
733 max_key_size: u32, 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 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 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 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 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 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 fn extract_digest(&mut self, buf: &mut [u8]) -> usize {
955 self.finalize_digest();
956 self.extract_finalized(buf)
957 }
958
959 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 self.state = OpState::Active;
971 }
972
973 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 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 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 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 self.state = OpState::Active;
1040 }
1041
1042 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 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 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 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 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 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 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}