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::cipher::{self, KeyInit, KeyIvInit};
13use aes::{Aes128, Aes192, Aes256};
14use cbc::{Decryptor as CbcDecryptor, Encryptor as CbcEncryptor};
15use cmac::Cmac;
16use ecb::{Decryptor as EcbDecryptor, Encryptor as EcbEncryptor};
17use hmac::Hmac;
18use rsa::rand_core::{self, CryptoRng, RngCore};
19use rsa::traits::{
20 PaddingScheme as RsaPaddingScheme, PublicKeyParts as _, SignatureScheme as RsaSignatureScheme,
21};
22use rsa::{Oaep, Pss, RsaPrivateKey};
23use sha1::digest::DynDigest as Digest;
24use sha1::{Sha1, digest};
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 rand_core::impls::next_u32_via_fill(self)
74 }
75
76 fn next_u64(&mut self) -> u64 {
77 rand_core::impls::next_u64_via_fill(self)
78 }
79
80 fn fill_bytes(&mut self, dest: &mut [u8]) {
81 zx::cprng_draw(dest)
82 }
83
84 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), rand_core::Error> {
85 self.fill_bytes(dest);
86 Ok(())
87 }
88}
89
90impl CryptoRng for Rng {}
91
92impl p256::elliptic_curve::rand_core::TryRng for Rng {
93 type Error = p256::elliptic_curve::rand_core::Infallible;
94
95 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
96 Ok(self.next_u32())
97 }
98
99 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
100 Ok(self.next_u64())
101 }
102
103 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
104 self.fill_bytes(dest);
105 Ok(())
106 }
107}
108
109impl p256::elliptic_curve::rand_core::TryCryptoRng for Rng {}
110
111trait Mac {
113 fn output_size(&self) -> usize;
114
115 fn update(&mut self, data: &[u8]);
116
117 fn reset(&mut self);
118
119 fn finalize_into_reset(&mut self, out: &mut [u8]);
120
121 fn verify_reset(&mut self, expected: &[u8]) -> TeeResult;
123}
124
125macro_rules! impl_hmac_mac {
127 ($($t:ty),*) => {
128 $(
129 impl Mac for Hmac<$t> {
130 fn output_size(&self) -> usize {
131 <Self as digest::OutputSizeUser>::output_size()
132 }
133
134 fn update(&mut self, data: &[u8]) {
135 <Self as digest::Update>::update(self, data)
136 }
137
138 fn reset(&mut self) {
139 <Self as digest::Reset>::reset(self)
140 }
141
142 fn finalize_into_reset(&mut self, out: &mut [u8]) {
143 <Self as digest::FixedOutputReset>::finalize_into_reset(self, out.into())
144 }
145
146 fn verify_reset(&mut self, expected: &[u8]) -> TeeResult {
147 let finalized = <Self as digest::FixedOutputReset>::finalize_fixed_reset(self);
148 if finalized.as_slice() == expected { Ok(()) } else { Err(Error::MacInvalid) }
149 }
150 }
151 )*
152 };
153}
154impl_hmac_mac!(Sha1, Sha224, Sha256, Sha384, Sha512);
155
156macro_rules! impl_cmac_mac {
157 ($($t:ty),*) => {
158 $(
159 impl Mac for Cmac<$t> {
160 fn output_size(&self) -> usize {
161 <Self as cmac::digest::OutputSizeUser>::output_size()
162 }
163
164 fn update(&mut self, data: &[u8]) {
165 <Self as cmac::digest::Update>::update(self, data)
166 }
167
168 fn reset(&mut self) {
169 <Self as cmac::digest::Reset>::reset(self)
170 }
171
172 fn finalize_into_reset(&mut self, out: &mut [u8]) {
173 <Self as cmac::digest::FixedOutputReset>::finalize_into_reset(self, out.try_into().unwrap())
174 }
175
176 fn verify_reset(&mut self, expected: &[u8]) -> TeeResult {
177 let finalized = <Self as cmac::digest::FixedOutputReset>::finalize_fixed_reset(self);
178 if finalized.as_slice() == expected { Ok(()) } else { Err(Error::MacInvalid) }
179 }
180 }
181 )*
182 };
183}
184impl_cmac_mac!(Aes128, Aes192, Aes256);
185
186enum MacType {
188 AesCmac,
189 HmacSha1,
190 HmacSha224,
191 HmacSha256,
192 HmacSha384,
193 HmacSha512,
194}
195
196trait Cipher {
198 fn block_size(&self) -> usize;
199 fn set_iv(&mut self, iv: &[u8]);
200 fn reset(&mut self);
201 fn encrypt(&self, input: &[u8], output: &mut [u8]);
202 fn encrypt_in_place(&self, inout: &mut [u8]);
203 fn decrypt(&self, input: &[u8], output: &mut [u8]);
204 fn decrypt_in_place(&self, inout: &mut [u8]);
205}
206
207impl<C: PreCipher> Cipher for C {
208 fn set_iv(&mut self, iv: &[u8]) {
209 self.set_iv(iv)
210 }
211
212 fn reset(&mut self) {
213 self.reset()
214 }
215
216 fn block_size(&self) -> usize {
217 debug_assert_eq!(C::Encryptor::block_size(), C::Decryptor::block_size());
218 C::Encryptor::block_size()
219 }
220
221 fn encrypt(&self, input: &[u8], output: &mut [u8]) {
222 self.new_encryptor().encrypt(input, output);
223 }
224
225 fn encrypt_in_place(&self, inout: &mut [u8]) {
226 self.new_encryptor().encrypt_in_place(inout)
227 }
228
229 fn decrypt(&self, input: &[u8], output: &mut [u8]) {
230 self.new_decryptor().decrypt(input, output)
231 }
232
233 fn decrypt_in_place(&self, inout: &mut [u8]) {
234 self.new_decryptor().decrypt_in_place(inout)
235 }
236}
237
238trait PreCipher {
241 type Encryptor: Encryptor;
242 type Decryptor: Decryptor;
243
244 fn set_iv(&mut self, iv: &[u8]);
245 fn reset(&mut self);
246
247 fn new_encryptor(&self) -> Self::Encryptor;
250 fn new_decryptor(&self) -> Self::Decryptor;
251}
252
253trait Encryptor {
254 fn block_size() -> usize;
255 fn encrypt(&mut self, input: &[u8], output: &mut [u8]);
256 fn encrypt_in_place(&mut self, inout: &mut [u8]);
257}
258
259trait Decryptor {
260 fn block_size() -> usize;
261 fn decrypt(&mut self, input: &[u8], output: &mut [u8]);
262 fn decrypt_in_place(&mut self, inout: &mut [u8]);
263}
264
265struct CipherWithIv<E, D>
267where
268 E: Encryptor + KeyIvInit,
269 D: Decryptor + KeyIvInit,
270{
271 key: Vec<u8>,
272 iv: Vec<u8>,
273 phantom: PhantomData<(E, D)>,
274}
275
276impl<E, D> CipherWithIv<E, D>
277where
278 E: Encryptor + KeyIvInit,
279 D: Decryptor + KeyIvInit,
280{
281 fn new(key: &[u8]) -> Self {
282 Self { key: key.to_vec(), iv: Vec::new(), phantom: PhantomData::default() }
283 }
284}
285
286impl<E, D> PreCipher for CipherWithIv<E, D>
287where
288 E: Encryptor + KeyIvInit,
289 D: Decryptor + KeyIvInit,
290{
291 type Encryptor = E;
292 type Decryptor = D;
293
294 fn set_iv(&mut self, iv: &[u8]) {
295 self.iv = iv.to_vec()
296 }
297
298 fn reset(&mut self) {
299 self.iv.clear()
300 }
301
302 fn new_encryptor(&self) -> E {
303 E::new_from_slices(&self.key, &self.iv).unwrap()
304 }
305
306 fn new_decryptor(&self) -> D {
307 D::new_from_slices(&self.key, &self.iv).unwrap()
308 }
309}
310
311struct CipherWithoutIv<E, D>
313where
314 E: Encryptor + KeyInit,
315 D: Decryptor + KeyInit,
316{
317 key: Vec<u8>,
318 phantom: PhantomData<(E, D)>,
319}
320
321impl<E, D> CipherWithoutIv<E, D>
322where
323 E: Encryptor + KeyInit,
324 D: Decryptor + KeyInit,
325{
326 fn new(key: &[u8]) -> Self {
327 Self { key: key.to_vec(), phantom: PhantomData::default() }
328 }
329}
330
331impl<E, D> PreCipher for CipherWithoutIv<E, D>
332where
333 E: Encryptor + KeyInit,
334 D: Decryptor + KeyInit,
335{
336 type Encryptor = E;
337 type Decryptor = D;
338
339 fn set_iv(&mut self, _iv: &[u8]) {}
347
348 fn reset(&mut self) {}
349
350 fn new_encryptor(&self) -> E {
351 E::new_from_slice(&self.key).unwrap()
352 }
353 fn new_decryptor(&self) -> D {
354 D::new_from_slice(&self.key).unwrap()
355 }
356}
357
358macro_rules! rustcrypto_encryptor_and_decryptor {
366 ($encryptor:tt, $decryptor:tt) => {
367 impl<C> Encryptor for $encryptor<C>
368 where
369 C: cipher::BlockCipherEncrypt + cipher::BlockSizeUser,
370 $encryptor<C>: cipher::BlockModeEncrypt,
371 {
372 fn block_size() -> usize {
373 C::block_size()
374 }
375
376 fn encrypt(&mut self, input: &[u8], output: &mut [u8]) {
377 use cipher::BlockModeEncrypt;
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.encrypt_block_b2b(
385 in_block.try_into().unwrap(),
386 out_block.try_into().unwrap(),
387 );
388 }
389 }
390
391 fn encrypt_in_place(&mut self, inout: &mut [u8]) {
392 use cipher::BlockModeEncrypt;
393
394 for block in inout.chunks_exact_mut(C::block_size()) {
395 self.encrypt_block(block.try_into().unwrap())
396 }
397 }
398 }
399
400 impl<C> Decryptor for $decryptor<C>
401 where
402 C: cipher::BlockCipherDecrypt + cipher::BlockSizeUser,
403 $decryptor<C>: cipher::BlockModeDecrypt,
404 {
405 fn block_size() -> usize {
406 C::block_size()
407 }
408
409 fn decrypt(&mut self, input: &[u8], output: &mut [u8]) {
410 use cipher::BlockModeDecrypt;
411
412 assert!(output.len() >= input.len());
413 let block_size = C::block_size();
414 let chunks =
415 iter::zip(input.chunks_exact(block_size), output.chunks_exact_mut(block_size));
416 for (in_block, out_block) in chunks {
417 self.decrypt_block_b2b(
418 in_block.try_into().unwrap(),
419 out_block.try_into().unwrap(),
420 );
421 }
422 }
423
424 fn decrypt_in_place(&mut self, inout: &mut [u8]) {
425 use cipher::BlockModeDecrypt;
426
427 for block in inout.chunks_exact_mut(C::block_size()) {
428 self.decrypt_block(block.try_into().unwrap())
429 }
430 }
431 }
432 };
433}
434
435rustcrypto_encryptor_and_decryptor!(CbcEncryptor, CbcDecryptor);
436rustcrypto_encryptor_and_decryptor!(EcbEncryptor, EcbDecryptor);
437
438type AesCbcNopad<C> = CipherWithIv<cbc::Encryptor<C>, cbc::Decryptor<C>>;
439type Aes128CbcNopad = AesCbcNopad<Aes128>;
440type Aes192CbcNopad = AesCbcNopad<Aes192>;
441type Aes256CbcNopad = AesCbcNopad<Aes256>;
442
443type AesEcbNopad<C> = CipherWithoutIv<ecb::Encryptor<C>, ecb::Decryptor<C>>;
444type Aes128EcbNopad = AesEcbNopad<Aes128>;
445type Aes192EcbNopad = AesEcbNopad<Aes192>;
446type Aes256EcbNopad = AesEcbNopad<Aes256>;
447
448enum CipherType {
449 AesCbcNopad,
450 AesEcbNopad,
451}
452
453trait AsymmetricEncryptionKey {
454 fn decrypt(
455 &self,
456 params: &[Attribute],
457 input: &[u8],
458 output: &mut [u8],
459 ) -> Result<usize, ErrorWithSize>;
460}
461
462trait RsaPadding<D>: RsaPaddingScheme
463where
464 D: 'static + Digest + digest::Digest + Send + Sync,
465{
466 fn new() -> Self;
467}
468
469impl<D> RsaPadding<D> for Oaep
470where
471 D: 'static + Digest + digest::Digest + Send + Sync,
472{
473 fn new() -> Self {
474 Oaep::new::<D>()
475 }
476}
477
478struct RsaEncryptionKey<D, Padding>
479where
480 D: 'static + Digest + digest::Digest + Send + Sync,
481 Padding: RsaPadding<D>,
482{
483 private: Rc<RsaPrivateKey>,
484 phantom: PhantomData<(D, Padding)>,
485}
486
487impl<D, Padding> RsaEncryptionKey<D, Padding>
488where
489 D: 'static + Digest + digest::Digest + Send + Sync,
490 Padding: RsaPadding<D>,
491{
492 fn new(private: Rc<RsaPrivateKey>) -> Self {
493 Self { private, phantom: PhantomData::default() }
494 }
495}
496
497impl<D, Padding> AsymmetricEncryptionKey for RsaEncryptionKey<D, Padding>
498where
499 D: 'static + Digest + digest::Digest + Send + Sync,
500 Padding: RsaPadding<D>,
501{
502 fn decrypt(
503 &self,
504 params: &[Attribute],
505 input: &[u8],
506 output: &mut [u8],
507 ) -> Result<usize, ErrorWithSize> {
508 if !params.is_empty() {
509 unimplemented!();
510 }
511 let output_size = self.private.size() as usize;
512 if input.len() != output_size {
513 return Err(ErrorWithSize::new(Error::BadParameters));
514 }
515 if output.len() < output_size {
516 return Err(ErrorWithSize::short_buffer(output_size));
517 }
518
519 let decrypted = self.private.decrypt(Padding::new(), input).expect("Failed to decrypt");
520 let written = &mut output[..decrypted.len()];
521 written.copy_from_slice(&decrypted);
522 Ok(written.len())
523 }
524}
525
526enum AsymmetricEncryptionKeyType {
527 RsaOaepSha1,
528}
529
530trait AsymmetricSigningKey {
531 fn sign(
532 &self,
533 params: &[Attribute],
534 input: &[u8],
535 output: &mut [u8],
536 ) -> Result<usize, ErrorWithSize>;
537}
538
539trait RsaSignature<D>: RsaSignatureScheme
540where
541 D: 'static + Digest + digest::Digest + Send + Sync,
542{
543 fn new() -> Self;
544}
545
546impl<D> RsaSignature<D> for Pss
547where
548 D: 'static + Digest + digest::Digest + Send + Sync,
549{
550 fn new() -> Self {
551 Pss::new::<D>()
552 }
553}
554
555struct RsaSigningKey<D, Signature>
556where
557 D: 'static + Digest + digest::Digest + Send + Sync,
558 Signature: RsaSignature<D>,
559{
560 private: Rc<RsaPrivateKey>,
561 phantom: PhantomData<(D, Signature)>,
562}
563
564impl<D, Signature> RsaSigningKey<D, Signature>
565where
566 D: 'static + Digest + digest::Digest + Send + Sync,
567 Signature: RsaSignature<D>,
568{
569 fn new(private: Rc<RsaPrivateKey>) -> Self {
570 Self { private, phantom: PhantomData::default() }
571 }
572}
573
574impl<D, Signature> AsymmetricSigningKey for RsaSigningKey<D, Signature>
575where
576 D: 'static + Digest + digest::Digest + Send + Sync,
577 Signature: RsaSignature<D>,
578{
579 fn sign(
580 &self,
581 params: &[Attribute],
582 input: &[u8],
583 output: &mut [u8],
584 ) -> Result<usize, ErrorWithSize> {
585 assert!(params.is_empty());
586 let output_size = self.private.size() as usize;
587 if output.len() < output_size {
588 return Err(ErrorWithSize::short_buffer(output_size));
589 }
590
591 let signed = self
592 .private
593 .sign_with_rng(&mut Rng {}, Signature::new(), input)
594 .expect("Failed to sign");
595 let written = &mut output[..signed.len()];
596 written.copy_from_slice(&signed);
597 Ok(written.len())
598 }
599}
600
601enum AsymmetricSigningKeyType {
602 RsaPssSha1,
603}
604
605enum Helper {
608 Digest(Box<dyn Digest>),
609 Cipher(Option<Box<dyn Cipher>>, CipherType),
610 Mac(Option<Box<dyn Mac>>, MacType),
611 AsymmetricEncryptionKey(Option<Box<dyn AsymmetricEncryptionKey>>, AsymmetricEncryptionKeyType),
612 AsymmetricSigningKey(Option<Box<dyn AsymmetricSigningKey>>, AsymmetricSigningKeyType),
613}
614
615impl Helper {
616 fn new(algorithm: Algorithm) -> TeeResult<Self> {
617 match algorithm {
618 Algorithm::Sha1 => Ok(Helper::Digest(Box::new(Sha1::default()))),
619 Algorithm::Sha224 => Ok(Helper::Digest(Box::new(Sha224::default()))),
620 Algorithm::Sha256 => Ok(Helper::Digest(Box::new(Sha256::default()))),
621 Algorithm::Sha384 => Ok(Helper::Digest(Box::new(Sha384::default()))),
622 Algorithm::Sha512 => Ok(Helper::Digest(Box::new(Sha512::default()))),
623 Algorithm::AesCbcNopad => Ok(Helper::Cipher(None, CipherType::AesCbcNopad)),
624 Algorithm::AesEcbNopad => Ok(Helper::Cipher(None, CipherType::AesEcbNopad)),
625 Algorithm::AesCmac => Ok(Helper::Mac(None, MacType::AesCmac)),
626 Algorithm::HmacSha1 => Ok(Helper::Mac(None, MacType::HmacSha1)),
627 Algorithm::HmacSha224 => Ok(Helper::Mac(None, MacType::HmacSha224)),
628 Algorithm::HmacSha256 => Ok(Helper::Mac(None, MacType::HmacSha256)),
629 Algorithm::HmacSha384 => Ok(Helper::Mac(None, MacType::HmacSha384)),
630 Algorithm::HmacSha512 => Ok(Helper::Mac(None, MacType::HmacSha512)),
631 Algorithm::RsaesPkcs1OaepMgf1Sha1 => {
632 Ok(Helper::AsymmetricEncryptionKey(None, AsymmetricEncryptionKeyType::RsaOaepSha1))
633 }
634 Algorithm::RsassaPkcs1PssMgf1Sha1 => {
635 Ok(Helper::AsymmetricSigningKey(None, AsymmetricSigningKeyType::RsaPssSha1))
636 }
637 _ => Err(Error::NotSupported),
638 }
639 }
640
641 fn initialize(&mut self, key: &Key) {
642 match self {
643 Helper::Digest(digest) => {
644 assert!(matches!(key, Key::Data(NoKey {})));
646 digest.reset()
647 }
648 Helper::Cipher(cipher, cipher_type) => {
649 let Key::Aes(AesKey { secret }) = key else {
650 panic!("Wrong key type ({:?}) - expected AES", key.get_type());
651 };
652
653 match cipher_type {
654 CipherType::AesCbcNopad => {
655 let cbc: Box<dyn Cipher> = match secret.len() {
656 16 => Box::new(Aes128CbcNopad::new(&secret)),
657 24 => Box::new(Aes192CbcNopad::new(&secret)),
658 32 => Box::new(Aes256CbcNopad::new(&secret)),
659 len => panic!("Invalid AES key length: {len}"),
660 };
661 *cipher = Some(cbc);
662 }
663 CipherType::AesEcbNopad => {
664 let ecb: Box<dyn Cipher> = match secret.len() {
665 16 => Box::new(Aes128EcbNopad::new(&secret)),
666 24 => Box::new(Aes192EcbNopad::new(&secret)),
667 32 => Box::new(Aes256EcbNopad::new(&secret)),
668 len => panic!("Invalid AES key length: {len}"),
669 };
670 *cipher = Some(ecb);
671 }
672 }
673 }
674 Helper::Mac(mac, mac_type) => match mac_type {
675 MacType::AesCmac => {
676 let Key::Aes(AesKey { secret }) = key else {
677 panic!("Wrong key type ({:?}) - expected AES", key.get_type());
678 };
679 let cmac: Box<dyn Mac> = match secret.len() {
680 16 => Box::new(AesCmac128::new_from_slice(&secret).unwrap()),
681 24 => Box::new(AesCmac192::new_from_slice(&secret).unwrap()),
682 32 => Box::new(AesCmac256::new_from_slice(&secret).unwrap()),
683 len => panic!("Invalid AES key length: {len}"),
684 };
685 *mac = Some(cmac);
686 }
687 MacType::HmacSha1 => {
688 let Key::HmacSha1(HmacSha1Key { secret }) = key else {
689 panic!("Wrong key type ({:?}) - expected HMAC SHA1", key.get_type());
690 };
691 *mac = Some(Box::new(
692 <HmacSha1 as sha1::digest::KeyInit>::new_from_slice(&secret).unwrap(),
693 ))
694 }
695 MacType::HmacSha224 => {
696 let Key::HmacSha224(HmacSha224Key { secret }) = key else {
697 panic!("Wrong key type ({:?}) - expected HMAC SHA224", key.get_type());
698 };
699 *mac = Some(Box::new(
700 <HmacSha224 as sha1::digest::KeyInit>::new_from_slice(&secret).unwrap(),
701 ))
702 }
703 MacType::HmacSha256 => {
704 let Key::HmacSha256(HmacSha256Key { secret }) = key else {
705 panic!("Wrong key type ({:?}) - expected HMAC SHA256", key.get_type());
706 };
707 *mac = Some(Box::new(
708 <HmacSha256 as sha1::digest::KeyInit>::new_from_slice(&secret).unwrap(),
709 ))
710 }
711 MacType::HmacSha384 => {
712 let Key::HmacSha384(HmacSha384Key { secret }) = key else {
713 panic!("Wrong key type ({:?}) - expected HMAC SHA384", key.get_type());
714 };
715 *mac = Some(Box::new(
716 <HmacSha384 as sha1::digest::KeyInit>::new_from_slice(&secret).unwrap(),
717 ))
718 }
719 MacType::HmacSha512 => {
720 let Key::HmacSha512(HmacSha512Key { secret }) = key else {
721 panic!("Wrong key type ({:?}) - expected HMAC SHA512", key.get_type());
722 };
723 *mac = Some(Box::new(
724 <HmacSha512 as sha1::digest::KeyInit>::new_from_slice(&secret).unwrap(),
725 ))
726 }
727 },
728 Helper::AsymmetricEncryptionKey(aenc, aenc_type) => match aenc_type {
729 AsymmetricEncryptionKeyType::RsaOaepSha1 => {
730 let Key::RsaKeypair(rsa) = key else {
731 panic!("Wrong key type ({:?}) - expected RSA keypair", key.get_type());
732 };
733 *aenc = Some(Box::new(RsaEncryptionKey::<Sha1, Oaep>::new(rsa.private_key())));
734 }
735 },
736 Helper::AsymmetricSigningKey(asign, asign_type) => match asign_type {
737 AsymmetricSigningKeyType::RsaPssSha1 => {
738 let Key::RsaKeypair(rsa) = key else {
739 panic!("Wrong key type ({:?}) - expected RSA keypair", key.get_type());
740 };
741 *asign = Some(Box::new(RsaSigningKey::<Sha1, Pss>::new(rsa.private_key())));
742 }
743 },
744 }
745 }
746
747 fn reset(&mut self) {
748 match self {
749 Helper::Digest(digest) => digest.reset(),
750 Helper::Cipher(cipher, _) => {
751 if let Some(cipher) = cipher {
752 cipher.reset()
753 }
754 }
755 Helper::Mac(mac, _) => {
756 if let Some(mac) = mac {
757 mac.reset()
758 }
759 }
760 Helper::AsymmetricEncryptionKey(_, _) => {}
761 Helper::AsymmetricSigningKey(_, _) => {}
762 }
763 }
764}
765
766#[derive(Debug, Eq, PartialEq)]
767enum OpState {
768 Initial,
769 Active,
770 Extracting((Vec<u8>, usize)),
773}
774
775pub struct Operation {
776 algorithm: Algorithm,
777 mode: Mode,
778 key: Key,
779 max_key_size: u32, state: OpState,
781 helper: Helper,
782}
783
784impl Operation {
785 fn new(algorithm: Algorithm, mode: Mode, max_key_size: u32) -> TeeResult<Self> {
786 Ok(Self {
787 algorithm,
788 mode,
789 key: Key::Data(NoKey {}),
790 max_key_size,
791 state: OpState::Initial,
792 helper: Helper::new(algorithm)?,
793 })
794 }
795
796 fn as_digest(&mut self) -> &mut Box<dyn Digest> {
797 if let Helper::Digest(digest) = &mut self.helper {
798 digest
799 } else {
800 panic!("{:?} is not a digest algorithm", self.algorithm)
801 }
802 }
803
804 fn as_cipher(&mut self) -> &mut Box<dyn Cipher> {
805 if let Helper::Cipher(cipher, _) = &mut self.helper {
806 cipher.as_mut().expect("TEE_OperationSetKey() has not yet been called")
807 } else {
808 panic!("{:?} is not a cipher algorithm", self.algorithm)
809 }
810 }
811
812 fn as_mac(&mut self) -> &mut Box<dyn Mac> {
813 if let Helper::Mac(mac, _) = &mut self.helper {
814 mac.as_mut().expect("TEE_OperationSetKey() has not yet been called")
815 } else {
816 panic!("{:?} is not a MAC algorithm", self.algorithm)
817 }
818 }
819
820 fn as_asymmetric_encryption_key(&mut self) -> &mut Box<dyn AsymmetricEncryptionKey> {
821 if let Helper::AsymmetricEncryptionKey(aenc, _) = &mut self.helper {
822 aenc.as_mut().expect("TEE_OperationSetKey() has not yet been called")
823 } else {
824 panic!("{:?} is not a asymmetric encryption key algorithm", self.algorithm)
825 }
826 }
827
828 fn as_asymmetric_signing_key(&mut self) -> &mut Box<dyn AsymmetricSigningKey> {
829 if let Helper::AsymmetricSigningKey(aenc, _) = &mut self.helper {
830 aenc.as_mut().expect("TEE_OperationSetKey() has not yet been called")
831 } else {
832 panic!("{:?} is not a asymmetric signing key algorithm", self.algorithm)
833 }
834 }
835
836 fn is_extracting(&self) -> (bool, usize) {
839 if let OpState::Extracting((ref data, ref pos)) = self.state {
840 (true, data.len() - pos)
841 } else {
842 (false, 0)
843 }
844 }
845
846 fn reset(&mut self) {
847 self.helper.reset();
848 self.state = OpState::Initial;
849 }
850
851 fn set_key(&mut self, obj: Rc<RefCell<dyn Object>>) -> TeeResult {
852 let obj = obj.borrow();
853 let key = obj.key();
854
855 assert!(
856 key.max_size() <= self.max_key_size,
857 "Provided key size ({}) exceeds configured max ({})",
858 key.max_size(),
859 self.max_key_size
860 );
861
862 assert_eq!(
863 self.state,
864 OpState::Initial,
865 "Operation must be in the initial state (not {:?})",
866 self.state
867 );
868
869 match self.algorithm {
870 Algorithm::AesCbcNopad | Algorithm::AesEcbNopad => match self.mode {
871 Mode::Encrypt | Mode::Decrypt => {
872 let usage = obj.usage();
873 if self.mode == Mode::Encrypt {
874 assert!(usage.contains(Usage::ENCRYPT | Usage::VERIFY));
875 } else {
876 assert!(usage.contains(Usage::DECRYPT | Usage::SIGN));
877 }
878 }
879 _ => return Err(Error::NotImplemented),
880 },
881 Algorithm::Md5
882 | Algorithm::Sha1
883 | Algorithm::Sha224
884 | Algorithm::Sha256
885 | Algorithm::Sha384
886 | Algorithm::Sha512
887 | Algorithm::Sha3_224
888 | Algorithm::Sha3_256
889 | Algorithm::Sha3_384
890 | Algorithm::Sha3_512
891 | Algorithm::Shake128
892 | Algorithm::Shake256 => {
893 panic!("Algorithm {:?} has no associated object type", self.algorithm);
894 }
895 Algorithm::AesCmac
896 | Algorithm::HmacSha1
897 | Algorithm::HmacSha224
898 | Algorithm::HmacSha256
899 | Algorithm::HmacSha384
900 | Algorithm::HmacSha512 => {}
901 Algorithm::RsaesPkcs1OaepMgf1Sha1 => {}
902 Algorithm::RsassaPkcs1PssMgf1Sha1 => {}
903 _ => return Err(Error::NotImplemented),
904 };
905 self.key = key.clone();
906 self.helper.initialize(&self.key);
907 Ok(())
908 }
909
910 fn clear_key(&mut self) -> TeeResult {
911 self.key = Key::Data(NoKey {});
912 self.state = OpState::Initial;
913 Ok(())
914 }
915
916 fn extract_finalized(&mut self, buf: &mut [u8]) -> usize {
920 let OpState::Extracting((ref data, ref mut pos)) = self.state else {
921 panic!("Operation is not in the extracting state: {:?}", self.state);
922 };
923 if buf.is_empty() || *pos >= data.len() {
924 return 0;
925 }
926 let read_size = min(data.len() - *pos, buf.len());
927 let in_chunk = &data.as_slice()[*pos..(*pos + read_size)];
928 let out_chunk = &mut buf[..read_size];
929 out_chunk.copy_from_slice(in_chunk);
930 *pos += read_size;
931 read_size
932 }
933
934 fn update_digest(&mut self, chunk: &[u8]) {
936 assert_eq!(self.mode, Mode::Digest);
937 assert!(self.state == OpState::Initial || self.state == OpState::Active);
938 self.as_digest().update(chunk);
939 self.state = OpState::Active;
940 }
941
942 fn update_and_finalize_digest_into(
949 &mut self,
950 last_chunk: &[u8],
951 buf: &mut [u8],
952 ) -> Result<(), ErrorWithSize> {
953 assert_eq!(self.mode, Mode::Digest);
954
955 if let (true, left_to_extract) = self.is_extracting() {
956 assert!(last_chunk.is_empty());
957
958 if left_to_extract > buf.len() {
959 return Err(ErrorWithSize::short_buffer(left_to_extract));
960 }
961
962 let written = self.extract_digest(buf);
963 debug_assert_eq!(written, left_to_extract);
964 self.state = OpState::Initial;
965 return Ok(());
966 }
967
968 let buf = {
969 let digest = self.as_digest();
970 let output_size = digest.output_size();
971 if output_size > buf.len() {
972 return Err(ErrorWithSize::short_buffer(output_size));
973 }
974
975 if !last_chunk.is_empty() {
976 digest.update(last_chunk);
977 }
978 &mut buf[..output_size]
979 };
980
981 self.as_digest().finalize_into_reset(buf).unwrap();
982 self.state = OpState::Initial;
983 Ok(())
984 }
985
986 fn finalize_digest(&mut self) {
989 assert_eq!(self.mode, Mode::Digest);
990 let (extracting, _) = self.is_extracting();
991 if extracting {
992 return;
993 }
994
995 let bytes = self.as_digest().finalize_reset();
996 self.state = OpState::Extracting((Vec::from(bytes), 0));
997 }
998
999 fn extract_digest(&mut self, buf: &mut [u8]) -> usize {
1001 self.finalize_digest();
1002 self.extract_finalized(buf)
1003 }
1004
1005 fn init_cipher(&mut self, iv: &[u8]) {
1007 if self.state == OpState::Active {
1008 self.as_cipher().reset();
1009 } else {
1010 assert_eq!(self.state, OpState::Initial);
1011 }
1012
1013 self.as_cipher().set_iv(iv);
1014
1015 self.state = OpState::Active;
1017 }
1018
1019 fn update_cipher(&mut self, src: &[u8], dest: &mut [u8]) -> Result<(), ErrorWithSize> {
1022 assert_eq!(self.state, OpState::Active);
1023
1024 let block_size = self.as_cipher().block_size();
1025 let num_blocks_in = src.len() / block_size;
1026 let num_blocks_out = dest.len() / block_size;
1027
1028 if num_blocks_in > num_blocks_out {
1031 return Err(ErrorWithSize::short_buffer(num_blocks_in * block_size));
1032 }
1033
1034 if self.mode == Mode::Encrypt {
1035 self.as_cipher().encrypt(src, dest);
1036 } else {
1037 assert_eq!(self.mode, Mode::Decrypt);
1038 self.as_cipher().decrypt(src, dest);
1039 }
1040 Ok(())
1041 }
1042
1043 fn update_cipher_in_place(&mut self, inout: &mut [u8]) {
1044 assert_eq!(self.state, OpState::Active);
1045
1046 if self.mode == Mode::Encrypt {
1047 self.as_cipher().encrypt_in_place(inout);
1048 } else {
1049 assert_eq!(self.mode, Mode::Decrypt);
1050 self.as_cipher().decrypt_in_place(inout);
1051 }
1052 }
1053
1054 fn finalize_cipher(&mut self, src: &[u8], dest: &mut [u8]) -> Result<(), ErrorWithSize> {
1058 let block_size = self.as_cipher().block_size();
1059 assert_eq!(src.len() % block_size, 0);
1060 assert!(dest.len() >= src.len());
1061 self.update_cipher(src, dest)?;
1062 self.state = OpState::Initial;
1063 Ok(())
1064 }
1065
1066 fn finalize_cipher_in_place(&mut self, inout: &mut [u8]) {
1067 let block_size = self.as_cipher().block_size();
1068 assert_eq!(inout.len() % block_size, 0);
1069 self.update_cipher_in_place(inout);
1070 self.state = OpState::Initial;
1071 }
1072
1073 fn init_mac(&mut self, _iv: &[u8]) {
1075 assert_eq!(self.mode, Mode::Mac);
1076 assert!(self.state == OpState::Initial || self.state == OpState::Active);
1077
1078 if self.state == OpState::Active {
1079 self.as_mac().reset();
1080 }
1081
1082 self.state = OpState::Active;
1086 }
1087
1088 fn update_mac(&mut self, chunk: &[u8]) {
1090 assert_eq!(self.mode, Mode::Mac);
1091 assert_eq!(self.state, OpState::Active);
1092
1093 let mac = self.as_mac();
1094 if !chunk.is_empty() {
1095 mac.update(chunk);
1096 }
1097 }
1098
1099 fn compute_final_mac(
1101 &mut self,
1102 message: &[u8],
1103 output: &mut [u8],
1104 ) -> Result<(), ErrorWithSize> {
1105 assert_eq!(self.mode, Mode::Mac);
1106 assert_eq!(self.state, OpState::Active);
1107
1108 let output_size = self.as_mac().output_size();
1109 if output.len() < output_size {
1110 return Err(ErrorWithSize::short_buffer(output_size));
1111 }
1112
1113 let mac = self.as_mac();
1116 if !message.is_empty() {
1117 mac.update(message);
1118 }
1119 mac.finalize_into_reset(&mut output[..output_size]);
1120 self.state = OpState::Initial;
1121 Ok(())
1122 }
1123
1124 fn compare_final_mac(&mut self, message: &[u8], expected: &[u8]) -> TeeResult {
1126 self.update_mac(message);
1127 let result = self.as_mac().verify_reset(expected);
1128 self.state = OpState::Initial;
1129 result
1130 }
1131
1132 fn asymmetric_decrypt(
1134 &mut self,
1135 params: &[Attribute],
1136 src: &[u8],
1137 dest: &mut [u8],
1138 ) -> Result<usize, ErrorWithSize> {
1139 assert_eq!(self.mode, Mode::Decrypt);
1140 self.as_asymmetric_encryption_key().decrypt(params, src, dest)
1141 }
1142
1143 fn asymmetric_sign_digest(
1145 &mut self,
1146 params: &[Attribute],
1147 digest: &[u8],
1148 signature: &mut [u8],
1149 ) -> Result<usize, ErrorWithSize> {
1150 assert_eq!(self.mode, Mode::Sign);
1151 self.as_asymmetric_signing_key().sign(params, digest, signature)
1152 }
1153}
1154
1155pub struct Operations {
1156 operations: HashMap<OperationHandle, RefCell<Operation>>,
1157 next_operation_handle_value: OperationHandle,
1158}
1159
1160impl Operations {
1161 pub fn new() -> Self {
1162 Self {
1163 operations: HashMap::new(),
1164 next_operation_handle_value: OperationHandle::from_value(1),
1165 }
1166 }
1167
1168 pub fn allocate(
1169 &mut self,
1170 algorithm: Algorithm,
1171 mode: Mode,
1172 max_key_size: u32,
1173 ) -> TeeResult<OperationHandle> {
1174 let is_valid_key_size = match algorithm {
1180 Algorithm::AesCbcNopad | Algorithm::AesEcbNopad => {
1181 match mode {
1182 Mode::Encrypt | Mode::Decrypt => {}
1183 _ => {
1184 return Err(Error::NotSupported);
1185 }
1186 };
1187 AesKey::is_valid_size
1188 }
1189 Algorithm::Md5
1190 | Algorithm::Sha1
1191 | Algorithm::Sha224
1192 | Algorithm::Sha256
1193 | Algorithm::Sha384
1194 | Algorithm::Sha512
1195 | Algorithm::Sha3_224
1196 | Algorithm::Sha3_256
1197 | Algorithm::Sha3_384
1198 | Algorithm::Sha3_512
1199 | Algorithm::Shake128
1200 | Algorithm::Shake256 => {
1201 if mode != Mode::Digest {
1202 return Err(Error::NotSupported);
1203 }
1204 NoKey::is_valid_size
1205 }
1206 Algorithm::AesCmac => {
1207 if mode != Mode::Mac {
1208 return Err(Error::NotSupported);
1209 }
1210 AesKey::is_valid_size
1211 }
1212 Algorithm::HmacSha1 => {
1213 if mode != Mode::Mac {
1214 return Err(Error::NotSupported);
1215 }
1216 HmacSha1Key::is_valid_size
1217 }
1218 Algorithm::HmacSha224 => {
1219 if mode != Mode::Mac {
1220 return Err(Error::NotSupported);
1221 }
1222 HmacSha224Key::is_valid_size
1223 }
1224 Algorithm::HmacSha256 => {
1225 if mode != Mode::Mac {
1226 return Err(Error::NotSupported);
1227 }
1228 HmacSha256Key::is_valid_size
1229 }
1230 Algorithm::HmacSha384 => {
1231 if mode != Mode::Mac {
1232 return Err(Error::NotSupported);
1233 }
1234 HmacSha384Key::is_valid_size
1235 }
1236 Algorithm::HmacSha512 => {
1237 if mode != Mode::Mac {
1238 return Err(Error::NotSupported);
1239 }
1240 HmacSha512Key::is_valid_size
1241 }
1242 Algorithm::RsaesPkcs1OaepMgf1Sha1 => {
1243 if mode != Mode::Encrypt && mode != Mode::Decrypt {
1244 return Err(Error::NotSupported);
1245 }
1246 RsaKeypair::is_valid_size
1247 }
1248 Algorithm::RsassaPkcs1PssMgf1Sha1 => {
1249 if mode != Mode::Sign && mode != Mode::Verify {
1250 return Err(Error::NotSupported);
1251 }
1252 RsaKeypair::is_valid_size
1253 }
1254 _ => {
1255 inspect_stubs::track_stub!(
1256 TODO("https://fxbug.dev/360942581"),
1257 "unsupported algorithm",
1258 );
1259 return Err(Error::NotImplemented);
1260 }
1261 };
1262 if !is_valid_key_size(max_key_size) {
1263 return Err(Error::NotSupported);
1264 }
1265 let operation = Operation::new(algorithm, mode, max_key_size)?;
1266 let handle = self.allocate_operation_handle();
1267 let prev = self.operations.insert(handle, RefCell::new(operation));
1268 debug_assert!(prev.is_none());
1269 Ok(handle)
1270 }
1271
1272 fn allocate_operation_handle(&mut self) -> OperationHandle {
1273 let handle = self.next_operation_handle_value;
1274 self.next_operation_handle_value = OperationHandle::from_value(*handle + 1);
1275 handle
1276 }
1277
1278 fn get_mut(&self, operation: OperationHandle) -> RefMut<'_, Operation> {
1279 self.operations.get(&operation).unwrap().borrow_mut()
1280 }
1281
1282 pub fn free(&mut self, operation: OperationHandle) {
1283 if operation.is_null() {
1284 return;
1285 }
1286 let _ = self.operations.remove(&operation).unwrap();
1287 }
1288
1289 pub fn reset(&mut self, operation: OperationHandle) {
1290 self.get_mut(operation).reset()
1291 }
1292
1293 pub fn set_key(
1294 &mut self,
1295 operation: OperationHandle,
1296 key: Rc<RefCell<dyn Object>>,
1297 ) -> TeeResult {
1298 self.get_mut(operation).set_key(key)
1299 }
1300
1301 pub fn clear_key(&mut self, operation: OperationHandle) -> TeeResult {
1302 self.get_mut(operation).clear_key()
1303 }
1304
1305 pub fn update_digest(&mut self, operation: OperationHandle, chunk: &[u8]) {
1306 self.get_mut(operation).update_digest(chunk);
1307 }
1308
1309 pub fn update_and_finalize_digest_into(
1310 &mut self,
1311 operation: OperationHandle,
1312 last_chunk: &[u8],
1313 buf: &mut [u8],
1314 ) -> Result<(), ErrorWithSize> {
1315 self.get_mut(operation).update_and_finalize_digest_into(last_chunk, buf)
1316 }
1317
1318 pub fn extract_digest<'a>(&mut self, operation: OperationHandle, buf: &'a mut [u8]) -> usize {
1319 self.get_mut(operation).extract_digest(buf)
1320 }
1321
1322 pub fn init_cipher(&mut self, operation: OperationHandle, iv: &[u8]) {
1323 self.get_mut(operation).init_cipher(iv)
1324 }
1325
1326 pub fn update_cipher(
1327 &mut self,
1328 operation: OperationHandle,
1329 input: &[u8],
1330 output: &mut [u8],
1331 ) -> Result<(), ErrorWithSize> {
1332 self.get_mut(operation).update_cipher(input, output)
1333 }
1334
1335 pub fn update_cipher_in_place(&mut self, operation: OperationHandle, inout: &mut [u8]) {
1336 self.get_mut(operation).update_cipher_in_place(inout)
1337 }
1338
1339 pub fn finalize_cipher(
1340 &mut self,
1341 operation: OperationHandle,
1342 input: &[u8],
1343 output: &mut [u8],
1344 ) -> Result<(), ErrorWithSize> {
1345 self.get_mut(operation).finalize_cipher(input, output)
1346 }
1347
1348 pub fn finalize_cipher_in_place(&mut self, operation: OperationHandle, inout: &mut [u8]) {
1349 self.get_mut(operation).finalize_cipher_in_place(inout)
1350 }
1351
1352 pub fn init_mac(&mut self, operation: OperationHandle, iv: &[u8]) {
1353 self.get_mut(operation).init_mac(iv)
1354 }
1355
1356 pub fn update_mac(&mut self, operation: OperationHandle, chunk: &[u8]) {
1357 self.get_mut(operation).update_mac(chunk)
1358 }
1359
1360 pub fn compute_final_mac(
1361 &mut self,
1362 operation: OperationHandle,
1363 message: &[u8],
1364 mac: &mut [u8],
1365 ) -> Result<(), ErrorWithSize> {
1366 self.get_mut(operation).compute_final_mac(message, mac)
1367 }
1368
1369 pub fn compare_final_mac(
1370 &mut self,
1371 operation: OperationHandle,
1372 message: &[u8],
1373 mac: &[u8],
1374 ) -> TeeResult {
1375 self.get_mut(operation).compare_final_mac(message, mac)
1376 }
1377
1378 pub fn asymmetric_decrypt(
1379 &mut self,
1380 operation: OperationHandle,
1381 params: &[Attribute],
1382 src: &[u8],
1383 dest: &mut [u8],
1384 ) -> Result<usize, ErrorWithSize> {
1385 self.get_mut(operation).asymmetric_decrypt(params, src, dest)
1386 }
1387
1388 pub fn asymmetric_sign_digest(
1389 &mut self,
1390 operation: OperationHandle,
1391 params: &[Attribute],
1392 digest: &[u8],
1393 signature: &mut [u8],
1394 ) -> Result<usize, ErrorWithSize> {
1395 self.get_mut(operation).asymmetric_sign_digest(params, digest, signature)
1396 }
1397}
1398
1399#[cfg(test)]
1400mod tests {
1401 use super::*;
1402
1403 #[fuchsia::test]
1404 fn operation_lifecycle() -> Result<(), Error> {
1405 let mut operations = Operations::new();
1406
1407 let operation = operations.allocate(Algorithm::Sha256, Mode::Digest, 0).unwrap();
1408
1409 operations.free(operation);
1410
1411 Ok(())
1412 }
1413}