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