1#![allow(unused_assignments)]
8
9use crate::api::tee_api_mm::{TEE_CheckMemoryAccessRights, TEE_Free, TEE_Malloc, TEE_MemFill};
10use crate::api::tee_api_objects::{
11 __utee_from_attr, TEE_AllocateTransientObject, TEE_CopyObjectAttributes1,
12 TEE_FreeTransientObject, TEE_GetObjectInfo1, TEE_ResetTransientObject,
13};
14use crate::api::tee_api_panic::TEE_Panic;
15use crate::syscalls::syscall_table::{
16 _utee_asymm_operate, _utee_asymm_verify, _utee_authenc_dec_final, _utee_authenc_enc_final,
17 _utee_authenc_init, _utee_authenc_update_aad, _utee_authenc_update_payload, _utee_cipher_final,
18 _utee_cipher_init, _utee_cipher_update, _utee_cryp_derive_key, _utee_cryp_obj_get_info,
19 _utee_cryp_random_number_generate, _utee_cryp_state_alloc, _utee_cryp_state_copy,
20 _utee_cryp_state_free, _utee_hash_final, _utee_hash_init, _utee_hash_update,
21};
22
23use crate::tee_api_defines::*;
24use crate::tee_api_types::{
25 TEE_Attribute, TEE_ObjectHandle, TEE_ObjectInfo, TEE_OperationHandle, TEE_OperationInfo,
26 TEE_OperationInfoKey, TEE_OperationInfoMultiple, TEE_Result,
27};
28use mbedtls::hash::{Md, Type as MdType};
29
30use std::ptr;
31
32pub fn TEE_ALG_GET_CLASS(alg: u32) -> u32 {
43 (alg >> 24) & 0xFF
44}
45
46pub(crate) fn TEE_ALG_GET_MAIN_ALG(algo: u32) -> u32 {
47 match algo {
48 TEE_ALG_SM2_PKE => TEE_MAIN_ALGO_SM2_PKE,
49 TEE_ALG_SM2_KEP => TEE_MAIN_ALGO_SM2_KEP,
50 TEE_ALG_X25519 => TEE_MAIN_ALGO_X25519,
51 TEE_ALG_ED25519 => TEE_MAIN_ALGO_ED25519,
52 TEE_ALG_ECDSA_SHA1 | TEE_ALG_ECDSA_SHA224 | TEE_ALG_ECDSA_SHA256 | TEE_ALG_ECDSA_SHA384
53 | TEE_ALG_ECDSA_SHA512 => TEE_MAIN_ALGO_ECDSA,
54 TEE_ALG_HKDF => TEE_MAIN_ALGO_HKDF,
55 TEE_ALG_SHAKE128 => TEE_MAIN_ALGO_SHAKE128,
56 TEE_ALG_SHAKE256 => TEE_MAIN_ALGO_SHAKE256,
57 TEE_ALG_X448 => TEE_MAIN_ALGO_X448,
58 _ => algo & 0xff,
59 }
60}
61
62fn __tee_alg_key_type(main_alg: u32, with_private_key: bool) -> u32 {
84 let mut key_type = 0xA000_0000 | main_alg;
85 if with_private_key {
86 key_type |= 0x0100_0000;
87 }
88 key_type
89}
90
91pub fn TEE_ALG_GET_KEY_TYPE(alg: u32, with_private_key: bool) -> Result<(u32, u32), u32> {
92 let req_key_type;
93 let mut req_key_type2: u32 = 0;
94 match TEE_ALG_GET_MAIN_ALG(alg) {
95 TEE_MAIN_ALGO_MD5 => {
96 req_key_type = TEE_TYPE_HMAC_MD5;
97 }
98 TEE_MAIN_ALGO_SHA1 => {
99 req_key_type = TEE_TYPE_HMAC_SHA1;
100 }
101 TEE_MAIN_ALGO_SHA224 => {
102 req_key_type = TEE_TYPE_HMAC_SHA224;
103 }
104 TEE_MAIN_ALGO_SHA256 => {
105 req_key_type = TEE_TYPE_HMAC_SHA256;
106 }
107 TEE_MAIN_ALGO_SHA384 => {
108 req_key_type = TEE_TYPE_HMAC_SHA384;
109 }
110 TEE_MAIN_ALGO_SHA512 => {
111 req_key_type = TEE_TYPE_HMAC_SHA512;
112 }
113 TEE_MAIN_ALGO_SHA3_224 => {
114 req_key_type = TEE_TYPE_HMAC_SHA3_224;
115 }
116 TEE_MAIN_ALGO_SHA3_256 => {
117 req_key_type = TEE_TYPE_HMAC_SHA3_256;
118 }
119 TEE_MAIN_ALGO_SHA3_384 => {
120 req_key_type = TEE_TYPE_HMAC_SHA3_384;
121 }
122 TEE_MAIN_ALGO_SHA3_512 => {
123 req_key_type = TEE_TYPE_HMAC_SHA3_512;
124 }
125 TEE_MAIN_ALGO_SM3 => {
126 req_key_type = TEE_TYPE_HMAC_SM3;
127 }
128 TEE_MAIN_ALGO_AES => {
129 req_key_type = TEE_TYPE_AES;
130 }
131 TEE_MAIN_ALGO_DES => {
132 req_key_type = TEE_TYPE_DES;
133 }
134 TEE_MAIN_ALGO_DES3 => {
135 req_key_type = TEE_TYPE_DES3;
136 }
137 TEE_MAIN_ALGO_SM4 => {
138 req_key_type = TEE_TYPE_SM4;
139 }
140 TEE_MAIN_ALGO_RSA => {
141 if with_private_key {
142 req_key_type = TEE_TYPE_RSA_KEYPAIR;
143 } else {
144 req_key_type = TEE_TYPE_RSA_PUBLIC_KEY;
145 }
146 }
147 TEE_MAIN_ALGO_DSA | TEE_MAIN_ALGO_ECDSA | TEE_MAIN_ALGO_ECDH | TEE_MAIN_ALGO_ED25519 => {
148 req_key_type = __tee_alg_key_type(TEE_ALG_GET_MAIN_ALG(alg), with_private_key);
149 }
150 TEE_MAIN_ALGO_DH => {
151 req_key_type = TEE_TYPE_DH_KEYPAIR;
152 }
153 TEE_MAIN_ALGO_SM2_PKE => {
154 if with_private_key {
155 req_key_type = TEE_TYPE_SM2_PKE_KEYPAIR;
156 } else {
157 req_key_type = TEE_TYPE_SM2_PKE_PUBLIC_KEY;
158 }
159 }
160 TEE_MAIN_ALGO_SM2_DSA_SM3 => {
161 if with_private_key {
162 req_key_type = TEE_TYPE_SM2_DSA_KEYPAIR;
163 } else {
164 req_key_type = TEE_TYPE_SM2_DSA_PUBLIC_KEY;
165 }
166 }
167 TEE_MAIN_ALGO_SM2_KEP => {
168 req_key_type = TEE_TYPE_SM2_KEP_KEYPAIR;
169 req_key_type2 = TEE_TYPE_SM2_KEP_PUBLIC_KEY;
170 }
171 TEE_MAIN_ALGO_HKDF => {
172 req_key_type = TEE_TYPE_HKDF_IKM;
173 }
174 TEE_MAIN_ALGO_CONCAT_KDF => {
175 req_key_type = TEE_TYPE_CONCAT_KDF_Z;
176 }
177 TEE_MAIN_ALGO_PBKDF2 => {
178 req_key_type = TEE_TYPE_PBKDF2_PASSWORD;
179 }
180 TEE_MAIN_ALGO_X25519 => {
181 req_key_type = TEE_TYPE_X25519_KEYPAIR;
182 }
183 TEE_MAIN_ALGO_X448 => {
184 req_key_type = TEE_TYPE_X448_KEYPAIR;
185 }
186 _ => return Err(TEE_ERROR_BAD_PARAMETERS),
187 }
188 Ok((req_key_type, req_key_type2))
189}
190
191impl TEE_OperationHandle {
192 pub fn new(
194 info: TEE_OperationInfo,
195 key1: TEE_ObjectHandle,
196 key2: TEE_ObjectHandle,
197 operation_state: u32,
198 block_size: usize,
199 state: u32,
200 ) -> Self {
201 TEE_OperationHandle {
202 info,
203 key1,
204 key2,
205 operation_state,
206 buffer: core::ptr::null_mut(),
207 buffer_two_blocks: false,
208 block_size,
209 buffer_offs: 0,
210 state,
211 }
212 }
213
214 pub fn free_buffer(&mut self) {
216 if !self.buffer.is_null() {
217 TEE_Free(self.buffer as *mut core::ffi::c_void);
218 self.buffer = ptr::null_mut();
219 self.buffer_offs = 0;
220 }
221 }
222}
223
224impl Drop for TEE_OperationHandle {
225 fn drop(&mut self) {
226 self.free_buffer();
227 }
228}
229
230#[derive(Debug, PartialEq)]
232pub enum BufferError {
233 BufferNotAllocated,
234 InsufficientSpace,
235 AllocationFailed,
236}
237
238impl std::fmt::Display for BufferError {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 match self {
241 BufferError::BufferNotAllocated => write!(f, "Buffer not allocated"),
242 BufferError::InsufficientSpace => write!(f, "Insufficient space in buffer"),
243 BufferError::AllocationFailed => write!(f, "Memory allocation failed"),
244 }
245 }
246}
247
248impl std::error::Error for BufferError {}
249
250impl TEE_OperationHandle {
251 pub fn allocate_buffer_v2(&mut self, size: usize) -> std::result::Result<(), BufferError> {
253 let new_buffer = TEE_Malloc(size, TEE_MALLOC_FILL_ZERO);
255 if new_buffer.is_null() {
256 return Err(BufferError::AllocationFailed);
257 }
258
259 if !self.buffer.is_null() {
261 TEE_Free(self.buffer as *mut core::ffi::c_void);
262 }
263
264 self.buffer = new_buffer as *mut u8;
265 self.buffer_offs = 0;
266 Ok(())
267 }
268}
269
270#[derive(Debug, PartialEq)]
272enum OperationConfig {
273 Digest {
274 block_size: usize,
275 },
276 Cipher {
277 block_size: usize,
278 buffer_two_blocks: bool,
279 req_key_usage: u32,
280 with_private_key: bool,
281 },
282 AsymmetricSignature {
283 req_key_usage: u32,
284 with_private_key: bool,
285 },
286 AsymmetricEncryption {
287 req_key_usage: u32,
288 with_private_key: bool,
289 },
290 KeyDerivation {
291 req_key_usage: u32,
292 },
293 Mac {
294 req_key_usage: u32,
295 },
296}
297
298fn validate_algorithm_params(
300 algorithm: u32,
301 mode: u32,
302 max_key_size: u32,
303) -> Result<OperationConfig, TEE_Result> {
304 use crate::tee_api_defines::*;
305
306 match algorithm {
308 TEE_ALG_DSA_SHA1 => {
309 if max_key_size < 512 || max_key_size > 1024 || max_key_size % 64 != 0 {
310 return Err(TEE_ERROR_NOT_SUPPORTED);
311 }
312 }
313 TEE_ALG_DSA_SHA224 => {
314 if max_key_size != 2048 {
315 return Err(TEE_ERROR_NOT_SUPPORTED);
316 }
317 }
318 TEE_ALG_DSA_SHA256 => {
319 if max_key_size != 2048 && max_key_size != 3072 {
320 return Err(TEE_ERROR_NOT_SUPPORTED);
321 }
322 }
323 TEE_ALG_ECDSA_P192 | TEE_ALG_ECDH_P192 => {
324 if max_key_size != 192 {
325 return Err(TEE_ERROR_NOT_SUPPORTED);
326 }
327 }
328 TEE_ALG_ECDSA_P224 | TEE_ALG_ECDH_P224 => {
329 if max_key_size != 224 {
330 return Err(TEE_ERROR_NOT_SUPPORTED);
331 }
332 }
333 TEE_ALG_ECDSA_P256 | TEE_ALG_ECDH_P256 | TEE_ALG_SM2_PKE | TEE_ALG_SM2_DSA_SM3 => {
334 if max_key_size != 256 {
335 return Err(TEE_ERROR_NOT_SUPPORTED);
336 }
337 }
338 TEE_ALG_SM2_KEP => {
339 if max_key_size != 512 {
340 return Err(TEE_ERROR_NOT_SUPPORTED);
341 }
342 }
343 TEE_ALG_ECDSA_P384 | TEE_ALG_ECDH_P384 => {
344 if max_key_size != 384 {
345 return Err(TEE_ERROR_NOT_SUPPORTED);
346 }
347 }
348 TEE_ALG_ECDSA_P521 | TEE_ALG_ECDH_P521 => {
349 if max_key_size != 521 {
350 return Err(TEE_ERROR_NOT_SUPPORTED);
351 }
352 }
353 _ => {}
354 }
355
356 match algorithm {
358 TEE_ALG_MD5 | TEE_ALG_SHA1 | TEE_ALG_SHA224 | TEE_ALG_SHA256 | TEE_ALG_SHA384
360 | TEE_ALG_SHA512 | TEE_ALG_SM3 => {
361 if mode != TEE_MODE_DIGEST {
362 return Err(TEE_ERROR_NOT_SUPPORTED);
363 }
364 let digest_length = match algorithm & 0x000000FF {
365 0x01 => 16, 0x02 => 20, 0x03 => 28, 0x04 => 32, 0x05 => 48, 0x06 => 64, 0x07 => 32, _ => 0,
373 };
374 Ok(OperationConfig::Digest {
375 block_size: digest_length,
376 })
377 }
378
379 TEE_ALG_DES_CBC_MAC_NOPAD
381 | TEE_ALG_AES_CBC_MAC_NOPAD
382 | TEE_ALG_AES_CBC_MAC_PKCS5
383 | TEE_ALG_AES_CMAC
384 | TEE_ALG_DES_CBC_MAC_PKCS5
385 | TEE_ALG_DES3_CBC_MAC_NOPAD
386 | TEE_ALG_DES3_CBC_MAC_PKCS5
387 | TEE_ALG_HMAC_MD5
388 | TEE_ALG_HMAC_SHA1
389 | TEE_ALG_HMAC_SHA224
390 | TEE_ALG_HMAC_SHA256
391 | TEE_ALG_HMAC_SHA384
392 | TEE_ALG_HMAC_SHA512
393 | TEE_ALG_HMAC_SM3 => {
394 if mode != TEE_MODE_MAC {
395 return Err(TEE_ERROR_NOT_SUPPORTED);
396 }
397 Ok(OperationConfig::Mac {
398 req_key_usage: TEE_USAGE_MAC,
399 })
400 }
401
402 TEE_ALG_AES_ECB_NOPAD
404 | TEE_ALG_AES_CBC_NOPAD
405 | TEE_ALG_AES_CCM
406 | TEE_ALG_DES_ECB_NOPAD
407 | TEE_ALG_DES_CBC_NOPAD
408 | TEE_ALG_DES3_ECB_NOPAD
409 | TEE_ALG_DES3_CBC_NOPAD
410 | TEE_ALG_SM4_ECB_NOPAD
411 | TEE_ALG_SM4_CBC_NOPAD
412 | TEE_ALG_SM4_CTR => {
413 let main_alg = (algorithm & 0x00FF0000) >> 16;
414 let block_size = match main_alg {
415 0x1000 => 16, 0x4000 => 16, _ => 8,
418 };
419 Ok(OperationConfig::Cipher {
420 block_size,
421 buffer_two_blocks: false,
422 req_key_usage: 0, with_private_key: false, })
425 }
426
427 TEE_ALG_AES_CTS => {
429 let main_alg = (algorithm & 0x00FF0000) >> 16;
430 let block_size = match main_alg {
431 0x1000 => 16, 0x4000 => 16, _ => return Err(TEE_ERROR_NOT_SUPPORTED),
434 };
435 Ok(OperationConfig::Cipher {
436 block_size,
437 buffer_two_blocks: true,
438 req_key_usage: 0,
439 with_private_key: false,
440 })
441 }
442
443 TEE_ALG_AES_XTS => match mode {
444 TEE_MODE_ENCRYPT => Ok(OperationConfig::Cipher {
445 block_size: 16,
446 buffer_two_blocks: true,
447 req_key_usage: TEE_USAGE_ENCRYPT,
448 with_private_key: false,
449 }),
450 TEE_MODE_DECRYPT => Ok(OperationConfig::Cipher {
451 block_size: 16,
452 buffer_two_blocks: true,
453 req_key_usage: TEE_USAGE_DECRYPT,
454 with_private_key: true,
455 }),
456 _ => Err(TEE_ERROR_NOT_SUPPORTED),
457 },
458
459 TEE_ALG_AES_CTR => match mode {
461 TEE_MODE_ENCRYPT => Ok(OperationConfig::Cipher {
462 block_size: 1,
463 buffer_two_blocks: false,
464 req_key_usage: TEE_USAGE_ENCRYPT,
465 with_private_key: false,
466 }),
467 TEE_MODE_DECRYPT => Ok(OperationConfig::Cipher {
468 block_size: 1,
469 buffer_two_blocks: false,
470 req_key_usage: TEE_USAGE_DECRYPT,
471 with_private_key: true,
472 }),
473 _ => Err(TEE_ERROR_NOT_SUPPORTED),
474 },
475
476 TEE_ALG_AES_GCM | TEE_ALG_SM4_GCM => match mode {
478 TEE_MODE_ENCRYPT => Ok(OperationConfig::Cipher {
479 block_size: 1,
480 buffer_two_blocks: false,
481 req_key_usage: TEE_USAGE_ENCRYPT,
482 with_private_key: false,
483 }),
484 TEE_MODE_DECRYPT => Ok(OperationConfig::Cipher {
485 block_size: 1,
486 buffer_two_blocks: false,
487 req_key_usage: TEE_USAGE_DECRYPT,
488 with_private_key: true,
489 }),
490 _ => Err(TEE_ERROR_NOT_SUPPORTED),
491 },
492
493 TEE_ALG_ECDSA_P192
495 | TEE_ALG_ECDSA_P224
496 | TEE_ALG_ECDSA_P256
497 | TEE_ALG_ECDSA_P384
498 | TEE_ALG_ECDSA_P521
499 | TEE_ALG_SM2_DSA_SM3
500 | TEE_ALG_RSASSA_PKCS1_V1_5_MD5
501 | TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1
502 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA1
503 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA224
504 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA256
505 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA384
506 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA512
507 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1
508 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224
509 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256
510 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384
511 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 => match mode {
512 TEE_MODE_SIGN => Ok(OperationConfig::AsymmetricSignature {
513 req_key_usage: TEE_USAGE_SIGN,
514 with_private_key: true,
515 }),
516 TEE_MODE_VERIFY => Ok(OperationConfig::AsymmetricSignature {
517 req_key_usage: TEE_USAGE_VERIFY,
518 with_private_key: false,
519 }),
520 _ => Err(TEE_ERROR_NOT_SUPPORTED),
521 },
522
523 TEE_ALG_RSAES_PKCS1_V1_5
525 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1
526 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224
527 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256
528 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384
529 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512
530 | TEE_ALG_SM2_PKE => match mode {
531 TEE_MODE_ENCRYPT => Ok(OperationConfig::AsymmetricEncryption {
532 req_key_usage: TEE_USAGE_ENCRYPT,
533 with_private_key: false,
534 }),
535 TEE_MODE_DECRYPT => Ok(OperationConfig::AsymmetricEncryption {
536 req_key_usage: TEE_USAGE_DECRYPT,
537 with_private_key: true,
538 }),
539 _ => Err(TEE_ERROR_NOT_SUPPORTED),
540 },
541
542 TEE_ALG_RSA_NOPAD => match mode {
544 TEE_MODE_ENCRYPT => Ok(OperationConfig::AsymmetricEncryption {
545 req_key_usage: TEE_USAGE_ENCRYPT | TEE_USAGE_VERIFY,
546 with_private_key: false,
547 }),
548 TEE_MODE_DECRYPT => Ok(OperationConfig::AsymmetricEncryption {
549 req_key_usage: TEE_USAGE_DECRYPT | TEE_USAGE_SIGN,
550 with_private_key: true,
551 }),
552 _ => Err(TEE_ERROR_NOT_SUPPORTED),
553 },
554
555 TEE_ALG_DH_DERIVE_SHARED_SECRET
557 | TEE_ALG_ECDH_P192
558 | TEE_ALG_ECDH_P224
559 | TEE_ALG_ECDH_P256
560 | TEE_ALG_ECDH_P384
561 | TEE_ALG_ECDH_P521
562 | TEE_ALG_SM2_KEP => {
563 if mode != TEE_MODE_DERIVE {
564 return Err(TEE_ERROR_NOT_SUPPORTED);
565 }
566 Ok(OperationConfig::KeyDerivation {
567 req_key_usage: TEE_USAGE_DERIVE,
568 })
569 }
570
571 _ => Err(TEE_ERROR_NOT_SUPPORTED),
572 }
573}
574
575pub fn tee_alg_get_class(algo: u32) -> u32 {
577 match algo {
578 TEE_ALG_SM2_PKE => TEE_OPERATION_ASYMMETRIC_CIPHER,
579 TEE_ALG_SM2_KEP => TEE_OPERATION_KEY_DERIVATION,
580 TEE_ALG_RSASSA_PKCS1_V1_5_MD5
581 | TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1
582 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA1
583 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA224
584 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA256
585 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA384
586 | TEE_ALG_RSASSA_PKCS1_V1_5_SHA512 => TEE_OPERATION_ASYMMETRIC_SIGNATURE,
587 TEE_ALG_DES3_CBC_MAC_NOPAD | TEE_ALG_DES3_CBC_MAC_PKCS5 => TEE_OPERATION_MAC,
588 TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1
589 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224
590 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256
591 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384
592 | TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512 => TEE_OPERATION_ASYMMETRIC_SIGNATURE,
593 TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1
594 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224
595 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256
596 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384
597 | TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512 => TEE_OPERATION_ASYMMETRIC_CIPHER,
598 _ => (algo >> 28) & 0xF,
599 }
600}
601
602#[unsafe(no_mangle)]
632pub extern "C" fn TEE_AllocateOperation(
633 operation: *mut *mut TEE_OperationHandle,
634 algorithm: u32,
635 mode: u32,
636 max_key_size: u32,
637) -> TEE_Result {
638 use crate::tee_api_defines::*;
639
640 if operation.is_null() {
642 TEE_Panic(0);
643 return TEE_ERROR_GENERIC;
644 }
645
646 let config = match validate_algorithm_params(algorithm, mode, max_key_size) {
648 Ok(c) => c,
649 Err(e) => return e,
650 };
651
652 let operation_class = tee_alg_get_class(algorithm);
654 let digest_length = match algorithm & 0x000000FF {
655 0x01 => 16, 0x02 => 20, 0x03 => 28, 0x04 => 32, 0x05 => 48, 0x06 => 64, 0x07 => 32, _ => 0,
663 };
664 let _main_alg = (algorithm & 0x00FF0000) >> 16;
665
666 let mut handle_state = 0u32;
667
668 if algorithm == TEE_ALG_AES_XTS || algorithm == TEE_ALG_SM2_KEP {
670 handle_state = TEE_HANDLE_FLAG_EXPECT_TWO_KEYS;
671 }
672
673 let (block_size, buffer_two_blocks, req_key_usage, with_private_key) = match config {
674 OperationConfig::Digest { block_size } => {
675 handle_state |= TEE_HANDLE_FLAG_KEY_SET;
676 (block_size, false, 0, false)
677 }
678 OperationConfig::Cipher {
679 block_size,
680 buffer_two_blocks,
681 req_key_usage,
682 with_private_key,
683 } => (
684 block_size,
685 buffer_two_blocks,
686 req_key_usage,
687 with_private_key,
688 ),
689 OperationConfig::AsymmetricSignature {
690 req_key_usage,
691 with_private_key,
692 } => (1, false, req_key_usage, with_private_key),
693 OperationConfig::AsymmetricEncryption {
694 req_key_usage,
695 with_private_key,
696 } => (1, false, req_key_usage, with_private_key),
697 OperationConfig::KeyDerivation { req_key_usage } => (1, false, req_key_usage, true),
698 OperationConfig::Mac { req_key_usage } => (1, false, req_key_usage, false),
699 };
700
701 let op_info = TEE_OperationInfo {
703 algorithm,
704 operationClass: operation_class,
705 mode,
706 digestLength: digest_length,
707 maxKeySize: max_key_size,
708 keySize: 0,
709 requiredKeyUsage: req_key_usage,
710 handleState: handle_state,
711 };
712
713 let operation_ptr = TEE_Malloc(
715 core::mem::size_of::<TEE_OperationHandle>(),
716 TEE_MALLOC_FILL_ZERO,
717 );
718 if operation_ptr.is_null() {
719 return TEE_ERROR_OUT_OF_MEMORY;
720 }
721
722 let op_handle = unsafe { &mut *(operation_ptr as *mut TEE_OperationHandle) };
724 *op_handle = TEE_OperationHandle::new(
725 op_info,
726 ptr::null_mut(),
727 ptr::null_mut(),
728 TEE_OPERATION_STATE_INITIAL,
729 block_size,
730 0,
731 );
732
733 if block_size > 1 {
735 let buffer_size = if buffer_two_blocks {
736 block_size * 2
737 } else {
738 block_size
739 };
740 if op_handle.allocate_buffer_v2(buffer_size).is_err() {
741 TEE_Free(operation_ptr);
742 return TEE_ERROR_OUT_OF_MEMORY;
743 }
744 }
745 op_handle.buffer_two_blocks = buffer_two_blocks;
746
747 if operation_class != TEE_OPERATION_DIGEST {
749 let mut mks = max_key_size;
750 let res = TEE_ALG_GET_KEY_TYPE(algorithm, with_private_key);
751 let (key_type, key_type2) = match res {
752 Ok(res) => res,
753 Err(e) => return e,
754 };
755
756 if handle_state & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS != 0 {
757 mks /= 2;
758 }
759
760 let mut key1_ptr = core::ptr::null_mut();
761 let res = TEE_AllocateTransientObject(key_type, mks, &mut key1_ptr);
762 if res != TEE_SUCCESS {
763 TEE_Free(operation_ptr);
764 return res;
765 }
766 op_handle.key1 = key1_ptr;
767
768 if handle_state & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS != 0 {
769 let mut key2_ptr = core::ptr::null_mut();
770 let key2_type = if key_type2 != 0 { key_type2 } else { key_type };
771 let res = TEE_AllocateTransientObject(key2_type, mks, &mut key2_ptr);
772 if res != TEE_SUCCESS {
773 TEE_FreeTransientObject(op_handle.key1);
774 TEE_Free(operation_ptr);
775 return res;
776 }
777 op_handle.key2 = key2_ptr;
778 }
779 }
780
781 let mut state = 0u32;
783 let res = unsafe {
784 _utee_cryp_state_alloc(
785 algorithm as u64,
786 mode as u64,
787 op_handle.key1 as u64,
788 op_handle.key2 as u64,
789 &mut state,
790 )
791 };
792 if res != TEE_SUCCESS as usize {
793 TEE_FreeTransientObject(op_handle.key1);
794 TEE_FreeTransientObject(op_handle.key2);
795 TEE_Free(operation_ptr);
796 return res as TEE_Result;
797 }
798 op_handle.state = state;
799
800 if operation_class == TEE_OPERATION_DIGEST {
802 let res = unsafe { _utee_hash_init(state as u64, core::ptr::null(), 0) };
803 if res != TEE_SUCCESS as usize {
804 TEE_FreeTransientObject(op_handle.key1);
805 TEE_FreeTransientObject(op_handle.key2);
806 TEE_Free(operation_ptr);
807 return res as TEE_Result;
808 }
809 op_handle.operation_state |= TEE_HANDLE_FLAG_INITIALIZED;
810 }
811
812 op_handle.operation_state = TEE_OPERATION_STATE_INITIAL;
813
814 unsafe {
816 *operation = operation_ptr as *mut TEE_OperationHandle;
817 }
818
819 TEE_SUCCESS
820}
821
822#[unsafe(no_mangle)]
826pub extern "C" fn TEE_FreeOperation(operation: *mut TEE_OperationHandle) {
827 use crate::tee_api_defines::*;
828
829 if operation.is_null() {
831 return;
832 }
833
834 let op_handle = unsafe { &*operation };
836
837 if !op_handle.buffer.is_null() {
839 TEE_Free(op_handle.buffer as *mut core::ffi::c_void);
840 }
841 let res = unsafe { _utee_cryp_state_free(op_handle.state as u64) };
848 if res != TEE_SUCCESS as usize {
849 TEE_Panic(res as u32);
850 }
851}
852
853#[unsafe(no_mangle)]
862pub extern "C" fn TEE_GetOperationInfo(
863 operation: *mut TEE_OperationHandle,
864 operationInfo: *mut TEE_OperationInfo,
865) {
866 use crate::tee_api_defines::*;
867
868 if operation.is_null() {
870 TEE_Panic(0);
871 }
872
873 if operationInfo.is_null() {
875 TEE_Panic(0);
876 }
877
878 if cfg!(feature = "strict_annotation_checks") {
880 let res = TEE_CheckMemoryAccessRights(
881 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
882 operationInfo as *mut core::ffi::c_void,
883 std::mem::size_of::<TEE_OperationInfo>(),
884 );
885 if res != 0 {
886 eprintln!("[out] operationInfo: error {:#010x}", res);
887 TEE_Panic(0);
888 }
889 }
890
891 let op_handle = unsafe { &*operation };
893 unsafe {
894 *operationInfo = op_handle.info;
895 }
896
897 unsafe {
899 if (*operationInfo).handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS != 0 {
900 (*operationInfo).keySize = 0;
901 (*operationInfo).requiredKeyUsage = 0;
902 }
903 }
904}
905
906#[unsafe(no_mangle)]
918pub extern "C" fn TEE_GetOperationInfoMultiple(
919 operation: *mut TEE_OperationHandle,
920 op_info: *mut TEE_OperationInfoMultiple,
921 size: *mut usize,
922) -> TEE_Result {
923 use crate::tee_api_defines::*;
924
925 if operation.is_null() {
927 return TEE_ERROR_BAD_PARAMETERS;
928 }
929
930 if op_info.is_null() || size.is_null() {
932 TEE_Panic(0);
933 return TEE_ERROR_BAD_PARAMETERS;
934 }
935
936 if cfg!(feature = "strict_annotation_checks") {
938 let buffer_size = unsafe { *size };
939 let res = TEE_CheckMemoryAccessRights(
940 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
941 op_info as *mut core::ffi::c_void,
942 buffer_size,
943 );
944 if res != 0 {
945 eprintln!("[out] op_info: error {:#010x}", res);
946 TEE_Panic(0);
947 }
948
949 let res = TEE_CheckMemoryAccessRights(
950 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
951 size as *mut core::ffi::c_void,
952 std::mem::size_of::<usize>(),
953 );
954 if res != 0 {
955 eprintln!("[out] size: error {:#010x}", res);
956 TEE_Panic(0);
957 }
958 }
959
960 let op_info_size = std::mem::size_of::<TEE_OperationInfoMultiple>();
962 let buffer_size = unsafe { *size };
963 if buffer_size < op_info_size {
964 return TEE_ERROR_BAD_PARAMETERS;
965 }
966
967 let key_info_size = std::mem::size_of::<TEE_OperationInfoKey>();
969 let max_key_count = (buffer_size - op_info_size) / key_info_size;
970
971 TEE_MemFill(op_info as *mut core::ffi::c_void, 0, buffer_size);
973
974 let op_handle = unsafe { &mut *operation };
976 let two_keys = (op_handle.info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 0;
977
978 let result = if op_handle.info.mode == TEE_MODE_DIGEST {
979 unsafe {
981 (*op_info).numberOfKeys = 0;
982 }
983 TEE_SUCCESS
984 } else if !two_keys {
985 if max_key_count < 1 {
987 return TEE_ERROR_SHORT_BUFFER;
988 }
989
990 let mut kinfo = TEE_ObjectInfo {
991 objectType: 0,
992 objectSize: 0,
993 maxObjectSize: 0,
994 objectUsage: 0,
995 dataSize: 0,
996 dataPosition: 0,
997 handleFlags: 0,
998 };
999
1000 let res = TEE_GetObjectInfo1(op_handle.key1, &mut kinfo);
1001 if res != TEE_SUCCESS {
1002 return check_operation_info_multiple_result(res);
1003 }
1004
1005 unsafe {
1006 (*op_info)
1007 .keyInformation
1008 .add(0)
1009 .write(TEE_OperationInfoKey {
1010 keySize: kinfo.objectSize,
1011 requiredKeyUsage: op_handle.info.requiredKeyUsage,
1012 });
1013 (*op_info).numberOfKeys = 1;
1014 }
1015
1016 TEE_SUCCESS
1017 } else {
1018 if max_key_count < 2 {
1020 return TEE_ERROR_SHORT_BUFFER;
1021 }
1022
1023 let mut kinfo = TEE_ObjectInfo {
1024 objectType: 0,
1025 objectSize: 0,
1026 maxObjectSize: 0,
1027 objectUsage: 0,
1028 dataSize: 0,
1029 dataPosition: 0,
1030 handleFlags: 0,
1031 };
1032
1033 let res = TEE_GetObjectInfo1(op_handle.key1, &mut kinfo);
1035 if res != TEE_SUCCESS {
1036 return check_operation_info_multiple_result(res);
1037 }
1038
1039 unsafe {
1040 (*op_info)
1041 .keyInformation
1042 .add(0)
1043 .write(TEE_OperationInfoKey {
1044 keySize: kinfo.objectSize,
1045 requiredKeyUsage: op_handle.info.requiredKeyUsage,
1046 });
1047 }
1048
1049 let res = TEE_GetObjectInfo1(op_handle.key2, &mut kinfo);
1051 if res != TEE_SUCCESS {
1052 return check_operation_info_multiple_result(res);
1053 }
1054
1055 unsafe {
1056 (*op_info)
1057 .keyInformation
1058 .add(1)
1059 .write(TEE_OperationInfoKey {
1060 keySize: kinfo.objectSize,
1061 requiredKeyUsage: op_handle.info.requiredKeyUsage,
1062 });
1063 (*op_info).numberOfKeys = 2;
1064 }
1065
1066 TEE_SUCCESS
1067 };
1068
1069 if result == TEE_SUCCESS {
1071 unsafe {
1072 (*op_info).algorithm = op_handle.info.algorithm;
1073 (*op_info).operationClass = op_handle.info.operationClass;
1074 (*op_info).mode = op_handle.info.mode;
1075 (*op_info).digestLength = op_handle.info.digestLength;
1076 (*op_info).maxKeySize = op_handle.info.maxKeySize;
1077 (*op_info).handleState = op_handle.info.handleState;
1078 (*op_info).operationState = op_handle.operation_state;
1079 }
1080 }
1081
1082 check_operation_info_multiple_result(result)
1083}
1084
1085fn check_operation_info_multiple_result(res: TEE_Result) -> TEE_Result {
1087 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
1088 TEE_Panic(res as u32);
1089 }
1090 res
1091}
1092
1093fn reset_operation_state(operation: &mut TEE_OperationHandle) {
1105 operation.operation_state = TEE_OPERATION_STATE_INITIAL;
1107 operation.buffer_offs = 0;
1109
1110 if operation.info.operationClass == TEE_OPERATION_DIGEST {
1111 let res = unsafe { _utee_hash_init(operation.state as u64, core::ptr::null(), 0) };
1112 if res != TEE_SUCCESS as usize {
1113 TEE_Panic(res as u32);
1114 }
1115 operation.info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
1116 } else {
1117 operation.info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
1118 }
1119}
1120
1121#[unsafe(no_mangle)]
1129pub extern "C" fn TEE_ResetOperation(operation: *mut TEE_OperationHandle) {
1130 if operation.is_null() {
1132 TEE_Panic(TEE_PANIC_ID_TEE_RESETOPERATION);
1133 }
1134 let op_handle = unsafe { &*operation };
1135 if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0 {
1136 TEE_Panic(0);
1137 }
1138 unsafe {
1140 reset_operation_state(&mut *operation);
1141 }
1142}
1143
1144#[unsafe(no_mangle)]
1160pub extern "C" fn TEE_SetOperationKey(
1161 operation: *mut TEE_OperationHandle,
1162 key: TEE_ObjectHandle,
1163) -> TEE_Result {
1164 if operation.is_null() {
1166 TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
1167 return TEE_ERROR_BAD_PARAMETERS;
1168 }
1169
1170 let op_handle = unsafe { &mut *operation };
1172
1173 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) != 0 {
1174 TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
1175 }
1176
1177 set_operation_key(op_handle, key)
1178}
1179
1180fn set_operation_key(op_handle: &mut TEE_OperationHandle, key: TEE_ObjectHandle) -> TEE_Result {
1182 if key.is_null() {
1184 TEE_ResetTransientObject(op_handle.key1);
1186 op_handle.info.handleState &= !TEE_HANDLE_FLAG_KEY_SET;
1187
1188 if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
1190 reset_operation_state(op_handle);
1191 }
1192 return TEE_SUCCESS;
1193 }
1194
1195 if op_handle.info.operationClass == TEE_OPERATION_DIGEST {
1197 TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
1198 return TEE_ERROR_BAD_PARAMETERS;
1199 }
1200
1201 if (op_handle.info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) != 0 {
1203 TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
1204 return TEE_ERROR_BAD_PARAMETERS;
1205 }
1206
1207 let mut key_info = TEE_ObjectInfo {
1209 objectType: 0,
1210 objectSize: 0,
1211 maxObjectSize: 0,
1212 objectUsage: 0,
1213 dataSize: 0,
1214 dataPosition: 0,
1215 handleFlags: 0,
1216 };
1217
1218 let res = TEE_GetObjectInfo1(key, &mut key_info);
1219 if res != TEE_SUCCESS {
1220 TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
1221 return TEE_ERROR_BAD_PARAMETERS;
1222 }
1223
1224 if (key_info.objectUsage & op_handle.info.requiredKeyUsage) != op_handle.info.requiredKeyUsage {
1226 TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
1227 return TEE_ERROR_SECURITY;
1228 }
1229
1230 if op_handle.info.maxKeySize < key_info.objectSize {
1232 TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
1233 return TEE_ERROR_BAD_PARAMETERS;
1234 }
1235
1236 TEE_ResetTransientObject(op_handle.key1);
1238 op_handle.info.handleState &= !TEE_HANDLE_FLAG_KEY_SET;
1239
1240 let res = TEE_CopyObjectAttributes1(op_handle.key1, key);
1242 if res != TEE_SUCCESS {
1243 TEE_Panic(TEE_PANIC_ID_TEE_SETOPERATIONKEY);
1244 return TEE_ERROR_BAD_PARAMETERS;
1245 }
1246
1247 op_handle.info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
1249
1250 op_handle.info.keySize = key_info.objectSize;
1252
1253 if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
1255 reset_operation_state(op_handle);
1256 }
1257
1258 TEE_SUCCESS
1259}
1260
1261#[unsafe(no_mangle)]
1277pub extern "C" fn TEE_SetOperationKey2(
1278 operation: *mut TEE_OperationHandle,
1279 key1: TEE_ObjectHandle,
1280 key2: TEE_ObjectHandle,
1281) -> TEE_Result {
1282 if operation.is_null() {
1284 return TEE_ERROR_BAD_PARAMETERS;
1285 }
1286
1287 let op_handle = unsafe { &mut *operation };
1288
1289 if !operation.is_null() && !key1.is_null() && !key2.is_null() && key1 == key2 {
1291 return TEE_ERROR_SECURITY;
1292 }
1293
1294 if key1.is_null() && key2.is_null() {
1296 TEE_ResetTransientObject(op_handle.key1);
1298 TEE_ResetTransientObject(op_handle.key2);
1299 op_handle.info.handleState &= !TEE_HANDLE_FLAG_KEY_SET;
1300 if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
1301 reset_operation_state(op_handle);
1302 }
1303 return TEE_SUCCESS;
1304 } else if key1.is_null() || key2.is_null() {
1305 return TEE_ERROR_BAD_PARAMETERS;
1307 }
1308
1309 if op_handle.info.operationClass == TEE_OPERATION_DIGEST {
1311 return TEE_ERROR_BAD_PARAMETERS;
1312 }
1313
1314 if (op_handle.info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0 {
1316 return TEE_ERROR_BAD_PARAMETERS;
1317 }
1318
1319 let mut key_info1 = TEE_ObjectInfo {
1321 objectType: 0,
1322 objectSize: 0,
1323 maxObjectSize: 0,
1324 objectUsage: 0,
1325 dataSize: 0,
1326 dataPosition: 0,
1327 handleFlags: 0,
1328 };
1329
1330 let mut res = TEE_GetObjectInfo1(key1, &mut key_info1);
1331 if res != TEE_SUCCESS {
1332 return handle_result_error(res);
1333 }
1334
1335 if (key_info1.objectUsage & op_handle.info.requiredKeyUsage) != op_handle.info.requiredKeyUsage
1337 {
1338 return TEE_ERROR_BAD_PARAMETERS;
1339 }
1340
1341 let mut key_info2 = TEE_ObjectInfo {
1343 objectType: 0,
1344 objectSize: 0,
1345 maxObjectSize: 0,
1346 objectUsage: 0,
1347 dataSize: 0,
1348 dataPosition: 0,
1349 handleFlags: 0,
1350 };
1351
1352 res = TEE_GetObjectInfo1(key2, &mut key_info2);
1353 if res != TEE_SUCCESS {
1354 return if res == TEE_ERROR_CORRUPT_OBJECT {
1355 TEE_ERROR_CORRUPT_OBJECT_2
1356 } else {
1357 handle_result_error(res)
1358 };
1359 }
1360
1361 if (key_info2.objectUsage & op_handle.info.requiredKeyUsage) != op_handle.info.requiredKeyUsage
1363 {
1364 return TEE_ERROR_BAD_PARAMETERS;
1365 }
1366
1367 if key_info1.objectSize != key_info2.objectSize {
1369 return TEE_ERROR_BAD_PARAMETERS;
1370 }
1371
1372 if op_handle.info.maxKeySize < key_info1.objectSize {
1374 return TEE_ERROR_BAD_PARAMETERS;
1375 }
1376
1377 TEE_ResetTransientObject(op_handle.key1);
1379 TEE_ResetTransientObject(op_handle.key2);
1380 op_handle.info.handleState &= !TEE_HANDLE_FLAG_KEY_SET;
1381
1382 res = TEE_CopyObjectAttributes1(op_handle.key1, key1);
1384 if res != TEE_SUCCESS {
1385 return handle_result_error(res);
1386 }
1387
1388 res = TEE_CopyObjectAttributes1(op_handle.key2, key2);
1389 if res != TEE_SUCCESS {
1390 return if res == TEE_ERROR_CORRUPT_OBJECT {
1391 TEE_ERROR_CORRUPT_OBJECT_2
1392 } else {
1393 handle_result_error(res)
1394 };
1395 }
1396
1397 op_handle.info.handleState |= TEE_HANDLE_FLAG_KEY_SET;
1399
1400 op_handle.info.keySize = key_info1.objectSize;
1402
1403 if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
1405 reset_operation_state(op_handle);
1406 }
1407
1408 TEE_SUCCESS
1409}
1410
1411fn handle_result_error(res: TEE_Result) -> TEE_Result {
1413 match res {
1414 TEE_SUCCESS => TEE_SUCCESS,
1415 TEE_ERROR_CORRUPT_OBJECT => TEE_ERROR_CORRUPT_OBJECT,
1416 TEE_ERROR_CORRUPT_OBJECT_2 => TEE_ERROR_CORRUPT_OBJECT_2,
1417 TEE_ERROR_STORAGE_NOT_AVAILABLE => TEE_ERROR_STORAGE_NOT_AVAILABLE,
1418 TEE_ERROR_STORAGE_NOT_AVAILABLE_2 => TEE_ERROR_STORAGE_NOT_AVAILABLE_2,
1419 _ => {
1420 TEE_Panic(res as u32);
1421 res
1422 }
1423 }
1424}
1425
1426#[unsafe(no_mangle)]
1439pub extern "C" fn TEE_CopyOperation(
1440 dst_op: *mut TEE_OperationHandle,
1441 src_op: *mut TEE_OperationHandle,
1442) {
1443 if dst_op.is_null() || src_op.is_null() {
1445 TEE_Panic(0);
1446 }
1447
1448 let (dst_ref, src_ref) = unsafe { (&mut *dst_op, &*src_op) };
1450
1451 if dst_ref.info.algorithm != src_ref.info.algorithm {
1453 TEE_Panic(0);
1454 }
1455 if dst_ref.info.mode != src_ref.info.mode {
1456 TEE_Panic(0);
1457 }
1458
1459 if src_ref.info.operationClass != TEE_OPERATION_DIGEST {
1461 let (key1, key2) = if (src_ref.info.handleState & TEE_HANDLE_FLAG_KEY_SET) != 0 {
1462 (src_ref.key1, src_ref.key2)
1463 } else {
1464 (ptr::null_mut(), ptr::null_mut())
1465 };
1466
1467 if (src_ref.info.handleState & TEE_HANDLE_FLAG_EXPECT_TWO_KEYS) == 0 {
1468 let res = set_operation_key(dst_ref, key1);
1469 if res != TEE_SUCCESS {
1470 TEE_Panic(res as u32);
1471 }
1472 } else {
1473 let res = TEE_SetOperationKey2(dst_op, key1, key2);
1475 if res != TEE_SUCCESS {
1476 TEE_Panic(res as u32);
1477 }
1478 }
1479 }
1480
1481 dst_ref.info.handleState = src_ref.info.handleState;
1483 dst_ref.info.keySize = src_ref.info.keySize;
1484 dst_ref.info.digestLength = src_ref.info.digestLength;
1485 dst_ref.operation_state = src_ref.operation_state;
1486
1487 if dst_ref.buffer_two_blocks != src_ref.buffer_two_blocks
1489 || dst_ref.block_size != src_ref.block_size
1490 {
1491 TEE_Panic(0);
1492 }
1493
1494 if !dst_ref.buffer.is_null() {
1496 if src_ref.buffer.is_null() {
1497 TEE_Panic(0);
1498 }
1499
1500 let sz = if src_ref.buffer_two_blocks {
1501 src_ref.block_size * 2
1502 } else {
1503 src_ref.block_size
1504 };
1505
1506 unsafe {
1508 std::ptr::copy_nonoverlapping(src_ref.buffer, dst_ref.buffer, sz);
1509 }
1510 dst_ref.buffer_offs = src_ref.buffer_offs;
1511 } else if !src_ref.buffer.is_null() {
1512 TEE_Panic(0);
1513 }
1514
1515 let res = unsafe { _utee_cryp_state_copy(dst_ref.state as u64, src_ref.state as u64) };
1517 if res != TEE_SUCCESS as usize {
1518 TEE_Panic(res as u32);
1519 }
1520}
1521
1522fn init_hash_operation(
1533 operation: *mut TEE_OperationHandle,
1534 iv: *const core::ffi::c_void,
1535 iv_len: u32,
1536) {
1537 if operation.is_null() {
1539 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
1540 return;
1541 }
1542
1543 let res = unsafe { _utee_hash_init((*operation).state as u64, iv, iv_len as usize) };
1544 if res != TEE_SUCCESS as usize {
1545 TEE_Panic(res as u32);
1546 }
1547
1548 unsafe {
1550 (*operation).buffer_offs = 0;
1551 (*operation).info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
1553 }
1554}
1555
1556#[unsafe(no_mangle)]
1570pub extern "C" fn TEE_DigestUpdate(
1571 operation: *mut TEE_OperationHandle,
1572 chunk: *const core::ffi::c_void,
1573 chunk_size: usize,
1574) {
1575 if operation.is_null() {
1577 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
1578 return;
1579 }
1580
1581 let op_handle = unsafe { &mut *operation };
1583
1584 if op_handle.info.operationClass != TEE_OPERATION_DIGEST {
1585 TEE_Panic(TEE_ERROR_BAD_PARAMETERS);
1586 return;
1587 }
1588
1589 op_handle.operation_state = TEE_OPERATION_STATE_ACTIVE;
1591
1592 let res = unsafe { _utee_hash_update(op_handle.state as u64, chunk, chunk_size) };
1594
1595 if res != TEE_SUCCESS as usize {
1596 TEE_Panic(res as u32);
1597 }
1598}
1599
1600#[unsafe(no_mangle)]
1614pub extern "C" fn TEE_DigestDoFinal(
1615 operation: *mut TEE_OperationHandle,
1616 chunk: *const core::ffi::c_void,
1617 chunk_len: usize,
1618 hash: *mut core::ffi::c_void,
1619 hash_len: *mut usize,
1620) -> TEE_Result {
1621 if operation.is_null() {
1623 return TEE_ERROR_BAD_PARAMETERS;
1624 }
1625
1626 if chunk.is_null() && chunk_len > 0 {
1628 return TEE_ERROR_BAD_PARAMETERS;
1629 }
1630
1631 let op_handle = unsafe { &mut *operation };
1633
1634 if op_handle.info.operationClass != TEE_OPERATION_DIGEST {
1636 return TEE_ERROR_BAD_PARAMETERS;
1637 }
1638
1639 if op_handle.operation_state == TEE_OPERATION_STATE_EXTRACTING && chunk_len > 0 {
1641 return TEE_ERROR_BAD_PARAMETERS;
1642 }
1643
1644 if hash_len.is_null() {
1646 TEE_Panic(0);
1647 return TEE_ERROR_BAD_PARAMETERS;
1648 }
1649
1650 if cfg!(feature = "strict_annotation_checks") {
1652 let res = TEE_CheckMemoryAccessRights(
1653 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
1654 hash_len as *mut core::ffi::c_void,
1655 std::mem::size_of::<usize>(),
1656 );
1657 if res != 0 {
1658 eprintln!("[inout] hash_len: error {:#010x}", res);
1659 TEE_Panic(0);
1660 return TEE_ERROR_BAD_PARAMETERS;
1661 }
1662 }
1663
1664 let res = if op_handle.operation_state == TEE_OPERATION_STATE_EXTRACTING
1665 && !op_handle.buffer.is_null()
1666 {
1667 let len = std::cmp::min(op_handle.block_size - op_handle.buffer_offs, unsafe {
1672 *hash_len
1673 });
1674 unsafe {
1675 std::ptr::copy_nonoverlapping(
1676 op_handle.buffer.add(op_handle.buffer_offs),
1677 hash as *mut u8,
1678 len,
1679 );
1680 *hash_len = len;
1681 }
1682 TEE_SUCCESS
1683 } else {
1684 let mut hl = unsafe { *hash_len as u64 };
1685 let res =
1686 unsafe { _utee_hash_final(op_handle.state as u64, chunk, chunk_len, hash, &mut hl) };
1687 unsafe {
1688 *hash_len = hl as usize;
1689 }
1690
1691 if res != TEE_SUCCESS as usize {
1692 return res as TEE_Result;
1693 }
1694
1695 TEE_SUCCESS
1696 };
1697
1698 init_hash_operation(operation, core::ptr::null(), 0);
1700
1701 unsafe {
1703 (*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
1704 }
1705
1706 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
1708 TEE_Panic(res as u32);
1709 }
1710
1711 res
1712}
1713
1714#[unsafe(no_mangle)]
1724pub extern "C" fn TEE_DigestExtract(
1725 operation: *mut TEE_OperationHandle,
1726 hash: *mut core::ffi::c_void,
1727 hash_len: *mut usize,
1728) -> TEE_Result {
1729 if operation.is_null() {
1730 TEE_Panic(0);
1731 }
1732
1733 let op_handle = unsafe { &mut *operation };
1734 if op_handle.info.operationClass != TEE_OPERATION_DIGEST {
1735 TEE_Panic(0);
1736 }
1737
1738 if hash_len.is_null() {
1740 TEE_Panic(0);
1741 return TEE_ERROR_BAD_PARAMETERS;
1742 }
1743
1744 if cfg!(feature = "strict_annotation_checks") {
1746 let res = TEE_CheckMemoryAccessRights(
1747 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
1748 hash_len as *mut core::ffi::c_void,
1749 std::mem::size_of::<usize>(),
1750 );
1751 if res != 0 {
1752 eprintln!("[inout] hash_len: error {:#010x}", res);
1753 TEE_Panic(0);
1754 return TEE_ERROR_BAD_PARAMETERS;
1755 }
1756 }
1757
1758 if op_handle.buffer.is_null() {
1760 unsafe {
1762 (*operation).info.handleState |= TEE_HANDLE_FLAG_EXTRACTING;
1763 (*operation).operation_state = TEE_OPERATION_STATE_EXTRACTING;
1764 }
1765
1766 let mut hl = unsafe { *hash_len as u64 };
1767 let res = unsafe {
1768 _utee_hash_final(op_handle.state as u64, core::ptr::null(), 0, hash, &mut hl)
1769 };
1770 if res != TEE_SUCCESS as usize {
1771 TEE_Panic(0);
1772 return TEE_ERROR_BAD_PARAMETERS;
1773 }
1774
1775 unsafe {
1776 *hash_len = hl as usize;
1777 }
1778
1779 return TEE_SUCCESS;
1780 }
1781
1782 if op_handle.operation_state != TEE_OPERATION_STATE_EXTRACTING {
1784 let mut hl = op_handle.block_size as u64;
1785 let res = unsafe {
1786 _utee_hash_final(
1787 op_handle.state as u64,
1788 core::ptr::null(),
1789 0,
1790 op_handle.buffer as *mut core::ffi::c_void,
1791 &mut hl,
1792 )
1793 };
1794 if res != TEE_SUCCESS as usize {
1795 TEE_Panic(0);
1796 return TEE_ERROR_BAD_PARAMETERS;
1797 }
1798
1799 if hl as usize != op_handle.block_size {
1800 TEE_Panic(0);
1801 return TEE_ERROR_BAD_PARAMETERS;
1802 }
1803
1804 debug_assert!(op_handle.buffer_offs == 0, "buffer_offs should be 0");
1805
1806 unsafe {
1807 (*operation).info.handleState |= TEE_HANDLE_FLAG_EXTRACTING;
1808 (*operation).operation_state = TEE_OPERATION_STATE_EXTRACTING;
1809 }
1810 }
1811
1812 let len = std::cmp::min(op_handle.block_size - op_handle.buffer_offs, unsafe {
1814 *hash_len
1815 });
1816
1817 unsafe {
1819 std::ptr::copy_nonoverlapping(
1820 op_handle.buffer.add(op_handle.buffer_offs),
1821 hash as *mut u8,
1822 len,
1823 );
1824 *hash_len = len;
1825 }
1826
1827 unsafe {
1829 (*operation).buffer_offs += len;
1830 }
1831
1832 TEE_SUCCESS
1833}
1834
1835#[unsafe(no_mangle)]
1846pub extern "C" fn TEE_CipherInit(
1847 operation: *mut TEE_OperationHandle,
1848 iv: *const core::ffi::c_void,
1849 iv_len: usize,
1850) {
1851 use crate::tee_api_defines::*;
1852
1853 if operation.is_null() {
1855 TEE_Panic(0);
1856 return;
1857 }
1858
1859 let op_handle = unsafe { &mut *operation };
1861
1862 if op_handle.info.operationClass != TEE_OPERATION_CIPHER {
1864 TEE_Panic(0);
1865 return;
1866 }
1867
1868 if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0 || op_handle.key1.is_null() {
1870 TEE_Panic(0);
1871 return;
1872 }
1873
1874 if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
1876 TEE_ResetOperation(operation);
1877 }
1878
1879 if !iv.is_null() && iv_len > 0 {
1881 match op_handle.info.algorithm {
1882 TEE_ALG_AES_ECB_NOPAD
1883 | TEE_ALG_DES_ECB_NOPAD
1884 | TEE_ALG_DES3_ECB_NOPAD
1885 | TEE_ALG_SM4_ECB_NOPAD => {
1886 TEE_Panic(0);
1887 return;
1888 }
1889 _ => {}
1890 }
1891 }
1892
1893 unsafe {
1895 (*operation).operation_state = TEE_OPERATION_STATE_ACTIVE;
1896 }
1897
1898 let res = unsafe { _utee_cipher_init(op_handle.state as u64, iv, iv_len) };
1900 if res != TEE_SUCCESS as usize {
1901 TEE_Panic(res as u32);
1902 return;
1903 }
1904
1905 unsafe {
1907 (*operation).buffer_offs = 0;
1908 (*operation).info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
1909 }
1910}
1911
1912const fn roundup2(v: usize, r: usize) -> usize {
1914 (v + r - 1) & !(r - 1)
1915}
1916
1917type UpdateFunc = unsafe extern "C" fn(
1919 state: u64,
1920 src: *const core::ffi::c_void,
1921 slen: usize,
1922 dst: *mut core::ffi::c_void,
1923 dlen: *mut u64,
1924) -> usize;
1925
1926fn tee_buffer_update(
1945 op: &mut TEE_OperationHandle,
1946 update_func: UpdateFunc,
1947 src_data: *const core::ffi::c_void,
1948 mut src_len: usize,
1949 dest_data: *mut core::ffi::c_void,
1950 dest_len: *mut u64,
1951) -> TEE_Result {
1952 use crate::tee_api_defines::*;
1953
1954 if src_data.is_null() {
1956 if src_len > 0 {
1957 TEE_Panic(0);
1958 }
1959 unsafe {
1960 *dest_len = 0;
1961 }
1962 return TEE_SUCCESS;
1963 }
1964
1965 let mut src = src_data as *const u8;
1966 let mut dst = dest_data as *mut u8;
1967 let mut dlen = unsafe { *dest_len } as usize;
1968 let mut acc_dlen = 0usize;
1969
1970 let (buffer_size, buffer_left) = if op.buffer_two_blocks {
1972 (op.block_size * 2, 1usize)
1973 } else {
1974 (op.block_size, 0usize)
1975 };
1976
1977 if op.buffer_offs > 0 {
1979 let l = if op.buffer_offs < op.block_size {
1980 std::cmp::min(src_len, op.block_size - op.buffer_offs)
1981 } else {
1982 std::cmp::min(src_len, buffer_size - op.buffer_offs)
1983 };
1984
1985 unsafe {
1986 std::ptr::copy_nonoverlapping(src, op.buffer.add(op.buffer_offs), l);
1987 }
1988 op.buffer_offs += l;
1989 src = unsafe { src.add(l) };
1990 src_len -= l;
1991
1992 if op.buffer_offs % op.block_size != 0 {
1994 unsafe {
1995 *dest_len = acc_dlen as u64;
1996 }
1997 return TEE_SUCCESS;
1998 }
1999 }
2000
2001 if op.buffer_offs > 0 && op.buffer_offs + src_len >= buffer_size + buffer_left {
2003 let mut l = roundup2(op.buffer_offs + src_len - buffer_size, op.block_size);
2004 l = std::cmp::min(op.buffer_offs, l);
2005
2006 if !op.buffer_two_blocks {
2008 l = op.block_size;
2009 }
2010
2011 let mut tmp_dlen = dlen as u64;
2012 let res = unsafe {
2013 update_func(
2014 op.state as u64,
2015 op.buffer as *const core::ffi::c_void,
2016 l,
2017 dst as *mut core::ffi::c_void,
2018 &mut tmp_dlen,
2019 )
2020 };
2021
2022 if res != TEE_SUCCESS as usize {
2023 TEE_Panic(res as u32);
2024 }
2025
2026 let tmp_dlen = tmp_dlen as usize;
2027 unsafe {
2028 dst = dst.add(tmp_dlen);
2029 }
2030 dlen -= tmp_dlen;
2031 acc_dlen += tmp_dlen;
2032 op.buffer_offs -= l;
2033
2034 if op.buffer_offs > 0 {
2036 unsafe {
2038 std::ptr::copy(op.buffer.add(l), op.buffer, buffer_size - l);
2039 std::ptr::copy_nonoverlapping(src, op.buffer.add(op.buffer_offs), src_len);
2040 }
2041 op.buffer_offs += src_len;
2042
2043 unsafe {
2044 *dest_len = acc_dlen as u64;
2045 }
2046 return TEE_SUCCESS;
2047 }
2048 }
2049
2050 if src_len >= buffer_size + buffer_left {
2052 let l = if op.buffer_two_blocks {
2054 roundup2(src_len - buffer_size, op.block_size)
2055 } else {
2056 roundup2(src_len - buffer_size + 1, op.block_size)
2057 };
2058
2059 let mut tmp_dlen = dlen as u64;
2060 let res = unsafe {
2061 update_func(
2062 op.state as u64,
2063 src as *const core::ffi::c_void,
2064 l,
2065 dst as *mut core::ffi::c_void,
2066 &mut tmp_dlen,
2067 )
2068 };
2069
2070 if res != TEE_SUCCESS as usize {
2071 TEE_Panic(res as u32);
2072 }
2073
2074 let tmp_dlen = tmp_dlen as usize;
2075 unsafe {
2076 src = src.add(l);
2077 }
2078 src_len -= l;
2079 acc_dlen += tmp_dlen;
2080 }
2081
2082 unsafe {
2084 std::ptr::copy_nonoverlapping(src, op.buffer.add(op.buffer_offs), src_len);
2085 }
2086 op.buffer_offs += src_len;
2087
2088 unsafe {
2089 *dest_len = acc_dlen as u64;
2090 }
2091 TEE_SUCCESS
2092}
2093
2094#[unsafe(no_mangle)]
2108pub extern "C" fn TEE_CipherUpdate(
2109 operation: *mut TEE_OperationHandle,
2110 src_data: *const core::ffi::c_void,
2111 src_len: usize,
2112 dest_data: *mut core::ffi::c_void,
2113 dest_len: *mut usize,
2114) -> TEE_Result {
2115 if operation.is_null() || (src_data.is_null() && src_len > 0) {
2117 return TEE_ERROR_BAD_PARAMETERS;
2118 }
2119
2120 if cfg!(feature = "strict_annotation_checks") {
2122 let res = TEE_CheckMemoryAccessRights(
2123 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
2124 dest_len as *mut core::ffi::c_void,
2125 std::mem::size_of::<usize>(),
2126 );
2127 if res != 0 {
2128 eprintln!("[inout] destLen: error {:#010x}", res);
2129 return TEE_ERROR_BAD_PARAMETERS;
2130 }
2131 }
2132
2133 let op_handle = unsafe { &mut *operation };
2135
2136 if op_handle.info.operationClass != TEE_OPERATION_CIPHER {
2138 return TEE_ERROR_BAD_PARAMETERS;
2139 }
2140
2141 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
2143 return TEE_ERROR_BAD_PARAMETERS;
2144 }
2145
2146 if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
2148 return TEE_ERROR_BAD_PARAMETERS;
2149 }
2150
2151 if src_data.is_null() && src_len == 0 {
2153 unsafe {
2154 *dest_len = 0;
2155 }
2156 return TEE_SUCCESS;
2157 }
2158
2159 let req_dlen = if op_handle.block_size > 1 {
2161 let base =
2162 ((op_handle.buffer_offs + src_len) / op_handle.block_size) * op_handle.block_size;
2163 if op_handle.buffer_two_blocks {
2164 if op_handle.buffer_offs + src_len > op_handle.block_size * 2 {
2165 let req = op_handle.buffer_offs + src_len - op_handle.block_size * 2;
2166 roundup2(req, op_handle.block_size)
2167 } else {
2168 0
2169 }
2170 } else {
2171 base
2172 }
2173 } else {
2174 src_len
2175 };
2176
2177 unsafe {
2182 if *dest_len < req_dlen {
2183 *dest_len = req_dlen;
2184 let res = TEE_ERROR_SHORT_BUFFER;
2185 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
2186 TEE_Panic(res as u32);
2187 }
2188 return res;
2189 }
2190 }
2191
2192 let mut dl = unsafe { *dest_len } as u64;
2193 let res = if op_handle.block_size > 1 {
2194 tee_buffer_update(
2195 op_handle,
2196 _utee_cipher_update,
2197 src_data,
2198 src_len,
2199 dest_data,
2200 &mut dl,
2201 )
2202 } else {
2203 if src_len > 0 {
2204 unsafe {
2205 _utee_cipher_update(
2206 op_handle.state as u64,
2207 src_data,
2208 src_len,
2209 dest_data,
2210 &mut dl,
2211 ) as TEE_Result
2212 }
2213 } else {
2214 dl = 0;
2215 TEE_SUCCESS
2216 }
2217 };
2218
2219 unsafe {
2220 *dest_len = dl as usize;
2221 }
2222
2223 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
2224 TEE_Panic(res as u32);
2225 }
2226
2227 res
2228}
2229
2230#[unsafe(no_mangle)]
2244pub extern "C" fn TEE_CipherDoFinal(
2245 operation: *mut TEE_OperationHandle,
2246 src_data: *const core::ffi::c_void,
2247 src_len: usize,
2248 dest_data: *mut core::ffi::c_void,
2249 dest_len: *mut usize,
2250) -> TEE_Result {
2251 if operation.is_null() || (src_data.is_null() && src_len > 0) {
2253 return TEE_ERROR_BAD_PARAMETERS;
2254 }
2255
2256 if !dest_len.is_null() {
2258 if cfg!(feature = "strict_annotation_checks") {
2259 let check_res = TEE_CheckMemoryAccessRights(
2260 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
2261 dest_len as *mut core::ffi::c_void,
2262 std::mem::size_of::<usize>(),
2263 );
2264 if check_res != 0 {
2265 eprintln!("[inout] destLen: error {:#010x}", check_res);
2266 return TEE_ERROR_BAD_PARAMETERS;
2267 }
2268 }
2269 }
2270
2271 let op_handle = unsafe { &mut *operation };
2273
2274 if op_handle.info.operationClass != TEE_OPERATION_CIPHER {
2276 return TEE_ERROR_BAD_PARAMETERS;
2277 }
2278
2279 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
2281 return TEE_ERROR_BAD_PARAMETERS;
2282 }
2283
2284 if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
2286 return TEE_ERROR_BAD_PARAMETERS;
2287 }
2288
2289 match op_handle.info.algorithm {
2293 TEE_ALG_AES_ECB_NOPAD
2294 | TEE_ALG_AES_CBC_NOPAD
2295 | TEE_ALG_DES_ECB_NOPAD
2296 | TEE_ALG_DES_CBC_NOPAD
2297 | TEE_ALG_DES3_ECB_NOPAD
2298 | TEE_ALG_DES3_CBC_NOPAD
2299 | TEE_ALG_SM4_ECB_NOPAD
2300 | TEE_ALG_SM4_CBC_NOPAD => {
2301 if (op_handle.buffer_offs + src_len) % op_handle.block_size != 0 {
2302 return TEE_ERROR_BAD_PARAMETERS;
2303 }
2304 }
2305 _ => {}
2306 }
2307
2308 let req_dlen = if op_handle.block_size > 1 {
2313 op_handle.buffer_offs + src_len
2314 } else {
2315 src_len
2316 };
2317
2318 let mut tmp_dlen = if !dest_len.is_null() {
2319 unsafe { *dest_len as u64 }
2320 } else {
2321 0u64
2322 };
2323
2324 if tmp_dlen < req_dlen as u64 {
2325 if !dest_len.is_null() {
2326 unsafe {
2327 *dest_len = req_dlen;
2328 }
2329 }
2330 let res = TEE_ERROR_SHORT_BUFFER;
2331 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
2332 TEE_Panic(res as u32);
2333 }
2334 return res;
2335 }
2336
2337 let mut res = TEE_SUCCESS;
2338 let mut dst = dest_data as *mut u8;
2339 let mut acc_dlen = 0usize;
2340
2341 if op_handle.block_size > 1 {
2342 if src_len > 0 {
2343 res = tee_buffer_update(
2344 unsafe { &mut *operation },
2345 _utee_cipher_update,
2346 src_data,
2347 src_len,
2348 dest_data,
2349 &mut tmp_dlen,
2350 );
2351
2352 if res != TEE_SUCCESS {
2353 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
2354 TEE_Panic(res as u32);
2355 }
2356 return res;
2357 }
2358
2359 let tmp_dlen_usize = tmp_dlen as usize;
2360 unsafe {
2361 dst = dst.add(tmp_dlen_usize);
2362 }
2363 acc_dlen += tmp_dlen_usize;
2364
2365 if !dest_len.is_null() {
2366 unsafe {
2367 tmp_dlen = *dest_len as u64 - acc_dlen as u64;
2368 }
2369 }
2370 }
2371
2372 res = unsafe {
2373 _utee_cipher_final(
2374 op_handle.state as u64,
2375 op_handle.buffer as *const core::ffi::c_void,
2376 op_handle.buffer_offs,
2377 dst as *mut core::ffi::c_void,
2378 &mut tmp_dlen,
2379 ) as TEE_Result
2380 };
2381 } else {
2382 res = unsafe {
2383 _utee_cipher_final(
2384 op_handle.state as u64,
2385 src_data,
2386 src_len,
2387 dst as *mut core::ffi::c_void,
2388 &mut tmp_dlen,
2389 ) as TEE_Result
2390 };
2391 }
2392
2393 if res != TEE_SUCCESS {
2394 if res != TEE_ERROR_SHORT_BUFFER {
2395 TEE_Panic(res as u32);
2396 }
2397 return res;
2398 }
2399
2400 acc_dlen += tmp_dlen as usize;
2401 if !dest_len.is_null() {
2402 unsafe {
2403 *dest_len = acc_dlen;
2404 }
2405 }
2406
2407 unsafe {
2409 (*operation).info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
2410 (*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
2411 }
2412
2413 res
2414}
2415
2416#[unsafe(no_mangle)]
2428pub extern "C" fn TEE_MACInit(
2429 operation: *mut TEE_OperationHandle,
2430 iv: *const core::ffi::c_void,
2431 iv_len: usize,
2432) {
2433 if operation.is_null() {
2435 TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
2436 return;
2437 }
2438
2439 let op_handle = unsafe { &*operation };
2441
2442 if op_handle.info.operationClass != TEE_OPERATION_MAC {
2444 TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
2445 return;
2446 }
2447
2448 if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0 || op_handle.key1.is_null() {
2450 TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
2451 return;
2452 }
2453
2454 if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
2456 TEE_ResetOperation(operation);
2457 }
2458
2459 unsafe {
2461 (*operation).operation_state = TEE_OPERATION_STATE_ACTIVE;
2462 }
2463
2464 init_hash_operation(operation, iv, iv_len as u32);
2466}
2467
2468#[unsafe(no_mangle)]
2483pub extern "C" fn TEE_MACUpdate(
2484 operation: *mut TEE_OperationHandle,
2485 chunk: *const core::ffi::c_void,
2486 chunk_size: usize,
2487) {
2488 if operation.is_null() {
2490 TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
2491 return;
2492 }
2493
2494 if chunk.is_null() && chunk_size > 0 {
2496 TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
2497 return;
2498 }
2499
2500 let op_handle = unsafe { &*operation };
2502
2503 if op_handle.info.operationClass != TEE_OPERATION_MAC {
2505 TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
2506 return;
2507 }
2508
2509 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
2511 TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
2512 return;
2513 }
2514
2515 if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
2517 TEE_Panic(TEE_PANIC_ID_TEE_MACINIT);
2518 return;
2519 }
2520
2521 let res = unsafe { _utee_hash_update(op_handle.state as u64, chunk, chunk_size) };
2523
2524 if res != TEE_SUCCESS as usize {
2525 TEE_Panic(res as u32);
2526 }
2527}
2528
2529#[unsafe(no_mangle)]
2543pub extern "C" fn TEE_MACComputeFinal(
2544 operation: *mut TEE_OperationHandle,
2545 message: *const core::ffi::c_void,
2546 message_len: usize,
2547 mac: *mut core::ffi::c_void,
2548 mac_len: *mut usize,
2549) -> TEE_Result {
2550 if operation.is_null()
2552 || (!message.is_null() && message_len == 0)
2553 || (message.is_null() && message_len > 0)
2554 {
2555 return TEE_ERROR_BAD_PARAMETERS;
2556 }
2557
2558 if cfg!(feature = "strict_annotation_checks") {
2560 let res = TEE_CheckMemoryAccessRights(
2561 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
2562 mac_len as *mut core::ffi::c_void,
2563 std::mem::size_of::<usize>(),
2564 );
2565 if res != 0 {
2566 eprintln!("[inout] mac_len: error {:#010x}", res);
2567 TEE_Panic(0);
2568 return TEE_ERROR_BAD_PARAMETERS;
2569 }
2570 }
2571
2572 let op_handle = unsafe { &mut *operation };
2574
2575 if op_handle.info.operationClass != TEE_OPERATION_MAC {
2577 return TEE_ERROR_BAD_PARAMETERS;
2578 }
2579
2580 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
2582 return TEE_ERROR_BAD_PARAMETERS;
2583 }
2584
2585 if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
2587 return TEE_ERROR_BAD_PARAMETERS;
2588 }
2589
2590 let mut ml = unsafe { *mac_len as u64 };
2592
2593 let res =
2595 unsafe { _utee_hash_final(op_handle.state as u64, message, message_len, mac, &mut ml) };
2596
2597 unsafe {
2599 *mac_len = ml as usize;
2600 }
2601
2602 if res != TEE_SUCCESS as usize {
2603 let result = res as TEE_Result;
2604 if result != TEE_ERROR_SHORT_BUFFER {
2605 TEE_Panic(result as u32);
2606 }
2607 return result;
2608 }
2609
2610 unsafe {
2612 (*operation).info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
2613 (*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
2614 }
2615
2616 TEE_SUCCESS as TEE_Result
2617}
2618
2619#[unsafe(no_mangle)]
2633pub extern "C" fn TEE_MACCompareFinal(
2634 operation: *mut TEE_OperationHandle,
2635 message: *const core::ffi::c_void,
2636 message_len: usize,
2637 mac: *const core::ffi::c_void,
2638 mac_len: usize,
2639) -> TEE_Result {
2640 if operation.is_null() {
2642 return TEE_ERROR_BAD_PARAMETERS;
2643 }
2644
2645 let op_handle = unsafe { &mut *operation };
2647
2648 if op_handle.info.operationClass != TEE_OPERATION_MAC {
2650 return TEE_ERROR_BAD_PARAMETERS;
2651 }
2652
2653 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
2655 return TEE_ERROR_BAD_PARAMETERS;
2656 }
2657
2658 if op_handle.operation_state != TEE_OPERATION_STATE_ACTIVE {
2660 return TEE_ERROR_BAD_PARAMETERS;
2661 }
2662
2663 let mut computed_mac = [0u8; TEE_MAX_HASH_SIZE as usize];
2665 let mut computed_mac_size = TEE_MAX_HASH_SIZE as usize;
2666
2667 let res = TEE_MACComputeFinal(
2669 operation,
2670 message,
2671 message_len,
2672 computed_mac.as_mut_ptr() as *mut core::ffi::c_void,
2673 &mut computed_mac_size,
2674 );
2675
2676 if res != TEE_SUCCESS {
2677 if res != TEE_ERROR_SHORT_BUFFER {
2678 TEE_Panic(res as u32);
2679 }
2680 return res;
2681 }
2682
2683 if computed_mac_size != mac_len {
2685 return TEE_ERROR_MAC_INVALID;
2686 }
2687
2688 let provided_mac = unsafe { std::slice::from_raw_parts(mac as *const u8, mac_len) };
2690
2691 if !consttime_memcmp(provided_mac, &computed_mac[..computed_mac_size]) {
2692 return TEE_ERROR_MAC_INVALID;
2693 }
2694
2695 unsafe {
2697 (*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
2698 }
2699
2700 TEE_SUCCESS
2701}
2702
2703fn consttime_memcmp(a: &[u8], b: &[u8]) -> bool {
2714 if a.len() != b.len() {
2715 return false;
2716 }
2717
2718 let mut result = 0u8;
2719 for (x, y) in a.iter().zip(b.iter()) {
2720 result |= x ^ y;
2721 }
2722 result == 0
2723}
2724
2725#[unsafe(no_mangle)]
2740pub extern "C" fn TEE_AEInit(
2741 operation: *mut TEE_OperationHandle,
2742 nonce: *const core::ffi::c_void,
2743 nonce_len: usize,
2744 tag_len: u32,
2745 aad_len: usize,
2746 payload_len: usize,
2747) -> TEE_Result {
2748 if operation.is_null() || nonce.is_null() {
2750 return TEE_ERROR_BAD_PARAMETERS;
2751 }
2752
2753 let op_handle = unsafe { &mut *operation };
2755
2756 if op_handle.info.operationClass != TEE_OPERATION_AE {
2758 return TEE_ERROR_BAD_PARAMETERS;
2759 }
2760
2761 if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
2763 return TEE_ERROR_BAD_PARAMETERS;
2764 }
2765
2766 if op_handle.info.algorithm == TEE_ALG_AES_GCM {
2768 if tag_len < 96 || tag_len > 128 || (tag_len % 8 != 0) {
2770 return TEE_ERROR_NOT_SUPPORTED;
2771 }
2772 }
2773
2774 let res = unsafe {
2776 _utee_authenc_init(
2777 op_handle.state as u64,
2778 nonce,
2779 nonce_len,
2780 tag_len as usize / 8, aad_len,
2782 payload_len,
2783 )
2784 };
2785
2786 if res != TEE_SUCCESS as usize {
2787 let result = res as TEE_Result;
2788 if result != TEE_ERROR_NOT_SUPPORTED {
2789 TEE_Panic(result as u32);
2790 }
2791 return result;
2792 }
2793
2794 unsafe {
2796 (*operation).info.digestLength = (tag_len / 8) as u32; (*operation).buffer_offs = 0;
2798 (*operation).info.handleState |= TEE_HANDLE_FLAG_INITIALIZED;
2799 }
2800
2801 TEE_SUCCESS
2802}
2803
2804#[unsafe(no_mangle)]
2811pub extern "C" fn TEE_AEUpdateAAD(
2812 operation: *mut TEE_OperationHandle,
2813 aad_data: *const core::ffi::c_void,
2814 aad_data_len: usize,
2815) {
2816 if operation.is_null() || (aad_data.is_null() && aad_data_len > 0) {
2818 TEE_Panic(0);
2819 return;
2820 }
2821
2822 let op_handle = unsafe { &*operation };
2824
2825 if op_handle.info.operationClass != TEE_OPERATION_AE {
2827 TEE_Panic(0);
2828 return;
2829 }
2830
2831 if op_handle.operation_state != TEE_OPERATION_STATE_INITIAL {
2833 TEE_Panic(0);
2834 return;
2835 }
2836
2837 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
2839 TEE_Panic(0);
2840 return;
2841 }
2842
2843 let res = unsafe { _utee_authenc_update_aad(op_handle.state as u64, aad_data, aad_data_len) };
2845
2846 if res != TEE_SUCCESS as usize {
2847 TEE_Panic(res as u32);
2848 }
2849}
2850
2851fn ae_update_helper(
2864 operation: *mut TEE_OperationHandle,
2865 src: *const core::ffi::c_void,
2866 slen: usize,
2867 dst: *mut core::ffi::c_void,
2868 dlen: *mut usize,
2869) -> TEE_Result {
2870 use crate::tee_api_defines::*;
2871
2872 if src.is_null() && slen == 0 {
2874 unsafe {
2875 *dlen = 0;
2876 }
2877 return TEE_SUCCESS;
2878 }
2879
2880 if operation.is_null() {
2882 return TEE_ERROR_BAD_PARAMETERS;
2883 }
2884
2885 let op_handle = unsafe { &*operation };
2887
2888 if dlen.is_null() {
2890 return TEE_ERROR_BAD_PARAMETERS;
2891 }
2892
2893 let req_dlen = if op_handle.block_size > 1 {
2895 let total_size = op_handle.buffer_offs + slen;
2897 roundup2(total_size, op_handle.block_size)
2899 } else {
2900 slen
2901 };
2902
2903 let provided_dlen = unsafe { *dlen };
2905 if provided_dlen < req_dlen {
2906 unsafe {
2907 *dlen = req_dlen;
2908 }
2909 return TEE_ERROR_SHORT_BUFFER;
2910 }
2911
2912 let mut dl = provided_dlen as u64;
2914 let res = if op_handle.block_size > 1 {
2915 tee_buffer_update(
2917 unsafe { &mut *operation },
2918 _utee_authenc_update_payload,
2919 src,
2920 slen,
2921 dst,
2922 &mut dl,
2923 )
2924 } else {
2925 if slen > 0 {
2927 unsafe {
2928 _utee_authenc_update_payload(op_handle.state as u64, src, slen, dst, &mut dl)
2929 as TEE_Result
2930 }
2931 } else {
2932 dl = 0;
2933 TEE_SUCCESS
2934 }
2935 };
2936
2937 if res == TEE_SUCCESS {
2939 unsafe {
2940 *dlen = dl as usize;
2941 }
2942 }
2943
2944 res
2945}
2946
2947#[unsafe(no_mangle)]
2961pub extern "C" fn TEE_AEUpdate(
2962 operation: *mut TEE_OperationHandle,
2963 src_data: *const core::ffi::c_void,
2964 src_len: usize,
2965 dest_data: *mut core::ffi::c_void,
2966 dest_len: *mut usize,
2967) -> TEE_Result {
2968 if operation.is_null() || (src_data.is_null() && src_len > 0) {
2970 let res = TEE_ERROR_BAD_PARAMETERS;
2971 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
2972 TEE_Panic(res as u32);
2973 }
2974 return res;
2975 }
2976
2977 if !dest_data.is_null() && !dest_len.is_null() {
2979 if cfg!(feature = "strict_annotation_checks") {
2980 let check_res = TEE_CheckMemoryAccessRights(
2981 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
2982 dest_len as *mut core::ffi::c_void,
2983 std::mem::size_of::<usize>(),
2984 );
2985 if check_res != 0 {
2986 eprintln!("[inout] destLen: error {:#010x}", check_res);
2987 TEE_Panic(0);
2988 return TEE_ERROR_BAD_PARAMETERS;
2989 }
2990 }
2991 }
2992
2993 let op_handle = unsafe { &*operation };
2995
2996 if op_handle.info.operationClass != TEE_OPERATION_AE {
2998 let res = TEE_ERROR_BAD_PARAMETERS;
2999 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3000 TEE_Panic(res as u32);
3001 }
3002 return res;
3003 }
3004
3005 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
3007 let res = TEE_ERROR_BAD_PARAMETERS;
3008 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3009 TEE_Panic(res as u32);
3010 }
3011 return res;
3012 }
3013
3014 let res = ae_update_helper(operation, src_data, src_len, dest_data, dest_len);
3016 if res != TEE_ERROR_SHORT_BUFFER && src_len > 0 {
3017 unsafe {
3018 (*operation).operation_state = TEE_OPERATION_STATE_ACTIVE;
3019 }
3020 }
3021
3022 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3024 TEE_Panic(res as u32);
3025 }
3026
3027 res
3028}
3029
3030#[unsafe(no_mangle)]
3046pub extern "C" fn TEE_AEEncryptFinal(
3047 operation: *mut TEE_OperationHandle,
3048 src_data: *const core::ffi::c_void,
3049 src_len: usize,
3050 dest_data: *mut core::ffi::c_void,
3051 dest_len: *mut usize,
3052 tag: *mut core::ffi::c_void,
3053 tag_len: *mut usize,
3054) -> TEE_Result {
3055 let mut res = TEE_SUCCESS;
3056
3057 if operation.is_null() || (src_data.is_null() && src_len > 0) {
3059 res = TEE_ERROR_BAD_PARAMETERS;
3060 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3061 TEE_Panic(res as u32);
3062 }
3063 return res;
3064 }
3065
3066 if !dest_len.is_null() {
3068 if cfg!(feature = "strict_annotation_checks") {
3069 let check_res = TEE_CheckMemoryAccessRights(
3070 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
3071 dest_len as *mut core::ffi::c_void,
3072 std::mem::size_of::<usize>(),
3073 );
3074 if check_res != 0 {
3075 eprintln!("[inout] destLen: error {:#010x}", check_res);
3076 TEE_Panic(0);
3077 return TEE_ERROR_BAD_PARAMETERS;
3078 }
3079 }
3080 }
3081
3082 if !tag_len.is_null() {
3083 if cfg!(feature = "strict_annotation_checks") {
3084 let check_res = TEE_CheckMemoryAccessRights(
3085 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
3086 tag_len as *mut core::ffi::c_void,
3087 std::mem::size_of::<usize>(),
3088 );
3089 if check_res != 0 {
3090 eprintln!("[inout] tagLen: error {:#010x}", check_res);
3091 TEE_Panic(0);
3092 return TEE_ERROR_BAD_PARAMETERS;
3093 }
3094 }
3095 }
3096
3097 let op_handle = unsafe { &*operation };
3099
3100 if op_handle.info.operationClass != TEE_OPERATION_AE {
3102 let res = TEE_ERROR_BAD_PARAMETERS;
3103 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3104 TEE_Panic(res as u32);
3105 }
3106 return res;
3107 }
3108
3109 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
3111 let res = TEE_ERROR_BAD_PARAMETERS;
3112 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3113 TEE_Panic(res as u32);
3114 }
3115 return res;
3116 }
3117
3118 if dest_len.is_null() || tag_len.is_null() {
3120 res = TEE_ERROR_BAD_PARAMETERS;
3121 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3122 TEE_Panic(res as u32);
3123 }
3124 return res;
3125 }
3126
3127 let dest_len_val = unsafe { *dest_len };
3129 let tag_len_val = unsafe { *tag_len };
3130
3131 let req_dlen = op_handle.buffer_offs + src_len;
3133
3134 if dest_len_val < req_dlen {
3136 unsafe {
3137 *dest_len = req_dlen;
3138 }
3139 res = TEE_ERROR_SHORT_BUFFER;
3140 }
3141
3142 if tag_len_val < op_handle.info.digestLength as usize {
3144 unsafe {
3145 *tag_len = op_handle.info.digestLength as usize;
3146 }
3147 res = TEE_ERROR_SHORT_BUFFER;
3148 }
3149
3150 if res == TEE_ERROR_SHORT_BUFFER {
3151 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3152 TEE_Panic(res as u32);
3153 }
3154 return res;
3155 }
3156
3157 let mut acc_dlen = 0usize;
3162 let mut tl = tag_len_val as u64;
3163 let mut tmp_dlen = (dest_len_val - acc_dlen) as u64;
3164
3165 let dst = dest_data as *mut u8;
3166
3167 if op_handle.block_size > 1 {
3169 res = tee_buffer_update(
3171 unsafe { &mut *operation },
3172 _utee_authenc_update_payload,
3173 src_data,
3174 src_len,
3175 dest_data,
3176 &mut tmp_dlen,
3177 );
3178 if res != TEE_SUCCESS {
3179 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3180 TEE_Panic(res as u32);
3181 }
3182 return res;
3183 }
3184
3185 acc_dlen += tmp_dlen as usize;
3186 tmp_dlen = (dest_len_val - acc_dlen) as u64;
3187
3188 let buffer_ptr = op_handle.buffer as *const core::ffi::c_void;
3190 res = unsafe {
3191 _utee_authenc_enc_final(
3192 op_handle.state as u64,
3193 buffer_ptr,
3194 op_handle.buffer_offs,
3195 dst.add(acc_dlen) as *mut core::ffi::c_void,
3196 &mut tmp_dlen,
3197 tag,
3198 &mut tl,
3199 ) as TEE_Result
3200 };
3201 } else {
3202 res = unsafe {
3204 _utee_authenc_enc_final(
3205 op_handle.state as u64,
3206 src_data,
3207 src_len,
3208 dst as *mut core::ffi::c_void,
3209 &mut tmp_dlen,
3210 tag,
3211 &mut tl,
3212 ) as TEE_Result
3213 };
3214 }
3215
3216 unsafe {
3218 *tag_len = tl as usize;
3219 }
3220
3221 if res != TEE_SUCCESS {
3222 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3223 TEE_Panic(res as u32);
3224 }
3225 return res;
3226 }
3227
3228 acc_dlen += tmp_dlen as usize;
3229 unsafe {
3230 *dest_len = acc_dlen;
3231 }
3232
3233 unsafe {
3235 (*operation).info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
3236 (*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
3237 }
3238
3239 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3241 TEE_Panic(res as u32);
3242 }
3243
3244 res
3245}
3246
3247#[unsafe(no_mangle)]
3264pub extern "C" fn TEE_AEDecryptFinal(
3265 operation: *mut TEE_OperationHandle,
3266 src_data: *const core::ffi::c_void,
3267 src_len: usize,
3268 dest_data: *mut core::ffi::c_void,
3269 dest_len: *mut usize,
3270 tag: *const core::ffi::c_void,
3271 tag_len: usize,
3272) -> TEE_Result {
3273 let mut res = TEE_SUCCESS;
3274 if operation.is_null() || (src_data.is_null() && src_len > 0) {
3276 let res = TEE_ERROR_BAD_PARAMETERS;
3277 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
3278 TEE_Panic(res as u32);
3279 }
3280 return res;
3281 }
3282
3283 if !dest_len.is_null() {
3285 if cfg!(feature = "strict_annotation_checks") {
3286 let check_res = TEE_CheckMemoryAccessRights(
3287 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
3288 dest_len as *mut core::ffi::c_void,
3289 std::mem::size_of::<usize>(),
3290 );
3291 if check_res != 0 {
3292 eprintln!("[inout] destLen: error {:#010x}", check_res);
3293 TEE_Panic(0);
3294 return TEE_ERROR_BAD_PARAMETERS;
3295 }
3296 }
3297 } else {
3298 let res = TEE_ERROR_BAD_PARAMETERS;
3299 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
3300 TEE_Panic(res as u32);
3301 }
3302 return res;
3303 }
3304
3305 let op_handle = unsafe { &*operation };
3307
3308 if op_handle.info.operationClass != TEE_OPERATION_AE {
3310 let res = TEE_ERROR_BAD_PARAMETERS;
3311 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
3312 TEE_Panic(res as u32);
3313 }
3314 return res;
3315 }
3316
3317 if (op_handle.info.handleState & TEE_HANDLE_FLAG_INITIALIZED) == 0 {
3319 let res = TEE_ERROR_BAD_PARAMETERS;
3320 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
3321 TEE_Panic(res as u32);
3322 }
3323 return res;
3324 }
3325
3326 let req_dlen = op_handle.buffer_offs + src_len;
3328
3329 let dest_len_val = unsafe { *dest_len };
3331 if dest_len_val < req_dlen {
3332 unsafe {
3333 *dest_len = req_dlen;
3334 }
3335 let res = TEE_ERROR_SHORT_BUFFER;
3336 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
3337 TEE_Panic(res as u32);
3338 }
3339 return res;
3340 }
3341
3342 let mut acc_dlen = 0usize;
3344 let mut tmp_dlen = (dest_len_val - acc_dlen) as u64;
3345
3346 let dst = dest_data as *mut u8;
3347
3348 if op_handle.block_size > 1 {
3350 res = tee_buffer_update(
3352 unsafe { &mut *operation },
3353 _utee_authenc_update_payload,
3354 src_data,
3355 src_len,
3356 dest_data,
3357 &mut tmp_dlen,
3358 );
3359 if res != TEE_SUCCESS {
3360 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
3361 TEE_Panic(res as u32);
3362 }
3363 return res;
3364 }
3365
3366 acc_dlen += tmp_dlen as usize;
3367 tmp_dlen = (dest_len_val - acc_dlen) as u64;
3368
3369 let buffer_ptr = op_handle.buffer as *const core::ffi::c_void;
3371 res = unsafe {
3372 _utee_authenc_dec_final(
3373 op_handle.state as u64,
3374 buffer_ptr,
3375 op_handle.buffer_offs,
3376 dst.add(acc_dlen) as *mut core::ffi::c_void,
3377 &mut tmp_dlen,
3378 tag,
3379 tag_len,
3380 ) as TEE_Result
3381 };
3382 } else {
3383 res = unsafe {
3385 _utee_authenc_dec_final(
3386 op_handle.state as u64,
3387 src_data,
3388 src_len,
3389 dst as *mut core::ffi::c_void,
3390 &mut tmp_dlen,
3391 tag,
3392 tag_len,
3393 ) as TEE_Result
3394 };
3395 }
3396
3397 if res != TEE_SUCCESS {
3398 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
3399 TEE_Panic(res as u32);
3400 }
3401 return res;
3402 }
3403
3404 acc_dlen += tmp_dlen as usize;
3405 unsafe {
3406 *dest_len = acc_dlen;
3407 }
3408
3409 unsafe {
3411 (*operation).info.handleState &= !TEE_HANDLE_FLAG_INITIALIZED;
3412 (*operation).operation_state = TEE_OPERATION_STATE_INITIAL;
3413 }
3414
3415 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER && res != TEE_ERROR_MAC_INVALID {
3417 TEE_Panic(res as u32);
3418 }
3419
3420 res
3421}
3422
3423#[unsafe(no_mangle)]
3441pub extern "C" fn TEE_AsymmetricEncrypt(
3442 operation: *mut TEE_OperationHandle,
3443 params: *const TEE_Attribute,
3444 param_count: u32,
3445 src_data: *const core::ffi::c_void,
3446 src_len: usize,
3447 dest_data: *mut core::ffi::c_void,
3448 dest_len: *mut usize,
3449) -> TEE_Result {
3450 let mut res = TEE_SUCCESS;
3451
3452 if operation.is_null() || (src_data.is_null() && src_len > 0) {
3454 TEE_Panic(0);
3455 return TEE_ERROR_BAD_PARAMETERS;
3456 }
3457
3458 if !params.is_null() && param_count > 0 {
3460 if cfg!(feature = "strict_annotation_checks") {
3461 let check_res = TEE_CheckMemoryAccessRights(
3462 TEE_MEMORY_ACCESS_READ,
3463 params as *mut core::ffi::c_void,
3464 (param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
3465 );
3466 if check_res != 0 {
3467 eprintln!("[in] params: error {:#010x}", check_res);
3468 TEE_Panic(0);
3469 return TEE_ERROR_BAD_PARAMETERS;
3470 }
3471 }
3472 }
3473
3474 if !dest_len.is_null() {
3476 if cfg!(feature = "strict_annotation_checks") {
3477 let check_res = TEE_CheckMemoryAccessRights(
3478 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
3479 dest_len as *mut core::ffi::c_void,
3480 std::mem::size_of::<usize>(),
3481 );
3482 if check_res != 0 {
3483 eprintln!("[inout] destLen: error {:#010x}", check_res);
3484 TEE_Panic(0);
3485 return TEE_ERROR_BAD_PARAMETERS;
3486 }
3487 }
3488 } else {
3489 TEE_Panic(0);
3490 return TEE_ERROR_BAD_PARAMETERS;
3491 }
3492
3493 let op_handle = unsafe { &*operation };
3495
3496 if op_handle.key1.is_null() {
3498 TEE_Panic(0);
3499 return TEE_ERROR_BAD_PARAMETERS;
3500 }
3501
3502 if op_handle.info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER {
3504 TEE_Panic(0);
3505 return TEE_ERROR_BAD_PARAMETERS;
3506 }
3507
3508 if op_handle.info.mode != TEE_MODE_ENCRYPT {
3509 TEE_Panic(0);
3510 return TEE_ERROR_BAD_PARAMETERS;
3511 }
3512
3513 let mut dl = unsafe { *dest_len as u64 };
3515
3516 let mut ua = Vec::with_capacity(param_count as usize);
3518 ua.resize(
3519 param_count as usize,
3520 crate::utee_types::utee_attribute::default(),
3521 );
3522 unsafe {
3523 __utee_from_attr(ua.as_mut_ptr(), params, param_count);
3524 }
3525
3526 let syscall_res = unsafe {
3528 _utee_asymm_operate(
3529 op_handle.state as u64,
3530 ua.as_ptr(),
3531 param_count as u64,
3532 src_data,
3533 src_len,
3534 dest_data,
3535 &mut dl,
3536 )
3537 };
3538
3539 unsafe {
3541 *dest_len = dl as usize;
3542 }
3543
3544 res = syscall_res as TEE_Result;
3545
3546 if res != TEE_SUCCESS
3548 && res != TEE_ERROR_SHORT_BUFFER
3549 && res != TEE_ERROR_BAD_PARAMETERS
3550 && res != TEE_ERROR_CIPHERTEXT_INVALID
3551 && res != TEE_ERROR_NOT_SUPPORTED
3552 {
3553 TEE_Panic(res as u32);
3554 }
3555
3556 res
3557}
3558
3559#[unsafe(no_mangle)]
3577pub extern "C" fn TEE_AsymmetricDecrypt(
3578 operation: *mut TEE_OperationHandle,
3579 params: *const TEE_Attribute,
3580 param_count: u32,
3581 src_data: *const core::ffi::c_void,
3582 src_len: usize,
3583 dest_data: *mut core::ffi::c_void,
3584 dest_len: *mut usize,
3585) -> TEE_Result {
3586 let mut res = TEE_SUCCESS;
3587
3588 if operation.is_null() || (src_data.is_null() && src_len > 0) {
3590 TEE_Panic(0);
3591 return TEE_ERROR_BAD_PARAMETERS;
3592 }
3593
3594 if !params.is_null() && param_count > 0 {
3596 if cfg!(feature = "strict_annotation_checks") {
3597 let check_res = TEE_CheckMemoryAccessRights(
3598 TEE_MEMORY_ACCESS_READ,
3599 params as *mut core::ffi::c_void,
3600 (param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
3601 );
3602 if check_res != 0 {
3603 eprintln!("[in] params: error {:#010x}", check_res);
3604 TEE_Panic(0);
3605 return TEE_ERROR_BAD_PARAMETERS;
3606 }
3607 }
3608 }
3609
3610 if !dest_len.is_null() {
3612 if cfg!(feature = "strict_annotation_checks") {
3613 let check_res = TEE_CheckMemoryAccessRights(
3614 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
3615 dest_len as *mut core::ffi::c_void,
3616 std::mem::size_of::<usize>(),
3617 );
3618 if check_res != 0 {
3619 eprintln!("[inout] destLen: error {:#010x}", check_res);
3620 TEE_Panic(0);
3621 return TEE_ERROR_BAD_PARAMETERS;
3622 }
3623 }
3624 } else {
3625 TEE_Panic(0);
3626 return TEE_ERROR_BAD_PARAMETERS;
3627 }
3628
3629 let op_handle = unsafe { &*operation };
3631
3632 if op_handle.key1.is_null() {
3634 TEE_Panic(0);
3635 return TEE_ERROR_BAD_PARAMETERS;
3636 }
3637
3638 if op_handle.info.operationClass != TEE_OPERATION_ASYMMETRIC_CIPHER {
3640 TEE_Panic(0);
3641 return TEE_ERROR_BAD_PARAMETERS;
3642 }
3643
3644 if op_handle.info.mode != TEE_MODE_DECRYPT {
3645 TEE_Panic(0);
3646 return TEE_ERROR_BAD_PARAMETERS;
3647 }
3648
3649 let mut dl = unsafe { *dest_len as u64 };
3651
3652 let mut ua = Vec::with_capacity(param_count as usize);
3654 ua.resize(
3655 param_count as usize,
3656 crate::utee_types::utee_attribute::default(),
3657 );
3658 unsafe {
3659 __utee_from_attr(ua.as_mut_ptr(), params, param_count);
3660 }
3661
3662 let syscall_res = unsafe {
3664 _utee_asymm_operate(
3665 op_handle.state as u64,
3666 ua.as_ptr(),
3667 param_count as u64,
3668 src_data,
3669 src_len,
3670 dest_data,
3671 &mut dl,
3672 )
3673 };
3674
3675 unsafe {
3677 *dest_len = dl as usize;
3678 }
3679
3680 res = syscall_res as TEE_Result;
3682 if res != TEE_SUCCESS
3683 && res != TEE_ERROR_SHORT_BUFFER
3684 && res != TEE_ERROR_BAD_PARAMETERS
3685 && res != TEE_ERROR_CIPHERTEXT_INVALID
3686 && res != TEE_ERROR_NOT_SUPPORTED
3687 {
3688 TEE_Panic(res as u32);
3689 }
3690
3691 res
3692}
3693
3694#[unsafe(no_mangle)]
3710pub extern "C" fn TEE_AsymmetricSignDigest(
3711 operation: *mut TEE_OperationHandle,
3712 params: *const TEE_Attribute,
3713 param_count: u32,
3714 digest: *const core::ffi::c_void,
3715 digest_len: usize,
3716 signature: *mut core::ffi::c_void,
3717 signature_len: *mut usize,
3718) -> TEE_Result {
3719 let mut res = TEE_SUCCESS;
3720
3721 if operation.is_null() || (digest.is_null() && digest_len > 0) {
3723 TEE_Panic(0);
3724 return TEE_ERROR_BAD_PARAMETERS;
3725 }
3726
3727 if !params.is_null() && param_count > 0 {
3729 if cfg!(feature = "strict_annotation_checks") {
3730 let check_res = TEE_CheckMemoryAccessRights(
3731 TEE_MEMORY_ACCESS_READ,
3732 params as *mut core::ffi::c_void,
3733 (param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
3734 );
3735 if check_res != 0 {
3736 eprintln!("[in] params: error {:#010x}", check_res);
3737 TEE_Panic(0);
3738 return TEE_ERROR_BAD_PARAMETERS;
3739 }
3740 }
3741 }
3742
3743 if !signature_len.is_null() {
3745 if cfg!(feature = "strict_annotation_checks") {
3746 let check_res = TEE_CheckMemoryAccessRights(
3747 TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE,
3748 signature_len as *mut core::ffi::c_void,
3749 std::mem::size_of::<usize>(),
3750 );
3751 if check_res != 0 {
3752 eprintln!("[inout] signatureLen: error {:#010x}", check_res);
3753 TEE_Panic(0);
3754 return TEE_ERROR_BAD_PARAMETERS;
3755 }
3756 }
3757 } else {
3758 TEE_Panic(0);
3759 return TEE_ERROR_BAD_PARAMETERS;
3760 }
3761
3762 let op_handle = unsafe { &*operation };
3764
3765 if op_handle.key1.is_null() {
3767 TEE_Panic(0);
3768 return TEE_ERROR_BAD_PARAMETERS;
3769 }
3770
3771 if op_handle.info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE {
3773 TEE_Panic(0);
3774 return TEE_ERROR_BAD_PARAMETERS;
3775 }
3776
3777 if op_handle.info.mode != TEE_MODE_SIGN {
3778 TEE_Panic(0);
3779 return TEE_ERROR_BAD_PARAMETERS;
3780 }
3781
3782 let mut sl = unsafe { *signature_len as u64 };
3784
3785 let mut ua = Vec::with_capacity(param_count as usize);
3787 ua.resize(
3788 param_count as usize,
3789 crate::utee_types::utee_attribute::default(),
3790 );
3791 unsafe {
3792 __utee_from_attr(ua.as_mut_ptr(), params, param_count);
3793 }
3794
3795 let syscall_res = unsafe {
3797 _utee_asymm_operate(
3798 op_handle.state as u64,
3799 ua.as_ptr(),
3800 param_count as u64,
3801 digest,
3802 digest_len,
3803 signature,
3804 &mut sl,
3805 )
3806 };
3807
3808 unsafe {
3810 *signature_len = sl as usize;
3811 }
3812
3813 res = syscall_res as TEE_Result;
3815 if res != TEE_SUCCESS && res != TEE_ERROR_SHORT_BUFFER {
3816 TEE_Panic(res as u32);
3817 }
3818
3819 res
3820}
3821
3822#[unsafe(no_mangle)]
3838pub extern "C" fn TEE_AsymmetricVerifyDigest(
3839 operation: *mut TEE_OperationHandle,
3840 params: *const TEE_Attribute,
3841 param_count: u32,
3842 digest: *const core::ffi::c_void,
3843 digest_len: usize,
3844 signature: *const core::ffi::c_void,
3845 signature_len: usize,
3846) -> TEE_Result {
3847 let mut res = TEE_SUCCESS;
3848
3849 if operation.is_null()
3851 || (digest.is_null() && digest_len != 0)
3852 || (signature.is_null() && signature_len != 0)
3853 {
3854 TEE_Panic(0);
3855 return TEE_ERROR_BAD_PARAMETERS;
3856 }
3857
3858 if !params.is_null() && param_count > 0 {
3860 if cfg!(feature = "strict_annotation_checks") {
3861 let check_res = TEE_CheckMemoryAccessRights(
3862 TEE_MEMORY_ACCESS_READ,
3863 params as *mut core::ffi::c_void,
3864 (param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
3865 );
3866 if check_res != 0 {
3867 eprintln!("[in] params: error {:#010x}", check_res);
3868 TEE_Panic(0);
3869 return TEE_ERROR_BAD_PARAMETERS;
3870 }
3871 }
3872 }
3873
3874 if !digest.is_null() && digest_len > 0 {
3876 if cfg!(feature = "strict_annotation_checks") {
3877 let check_res = TEE_CheckMemoryAccessRights(
3878 TEE_MEMORY_ACCESS_READ,
3879 digest as *mut core::ffi::c_void,
3880 digest_len,
3881 );
3882 if check_res != 0 {
3883 eprintln!("[in] digest: error {:#010x}", check_res);
3884 TEE_Panic(0);
3885 return TEE_ERROR_BAD_PARAMETERS;
3886 }
3887 }
3888 }
3889
3890 if !signature.is_null() && signature_len > 0 {
3892 if cfg!(feature = "strict_annotation_checks") {
3893 let check_res = TEE_CheckMemoryAccessRights(
3894 TEE_MEMORY_ACCESS_READ,
3895 signature as *mut core::ffi::c_void,
3896 signature_len,
3897 );
3898 if check_res != 0 {
3899 eprintln!("[in] signature: error {:#010x}", check_res);
3900 TEE_Panic(0);
3901 return TEE_ERROR_BAD_PARAMETERS;
3902 }
3903 }
3904 }
3905
3906 let op_handle = unsafe { &*operation };
3908
3909 if op_handle.key1.is_null() {
3911 TEE_Panic(0);
3912 return TEE_ERROR_BAD_PARAMETERS;
3913 }
3914
3915 if op_handle.info.operationClass != TEE_OPERATION_ASYMMETRIC_SIGNATURE {
3917 TEE_Panic(0);
3918 return TEE_ERROR_BAD_PARAMETERS;
3919 }
3920
3921 if op_handle.info.mode != TEE_MODE_VERIFY {
3922 TEE_Panic(0);
3923 return TEE_ERROR_BAD_PARAMETERS;
3924 }
3925
3926 let mut ua = Vec::with_capacity(param_count as usize);
3928 ua.resize(
3929 param_count as usize,
3930 crate::utee_types::utee_attribute::default(),
3931 );
3932 unsafe {
3933 __utee_from_attr(ua.as_mut_ptr(), params, param_count);
3934 }
3935
3936 let syscall_res = unsafe {
3938 _utee_asymm_verify(
3939 op_handle.state as u64,
3940 ua.as_ptr(),
3941 param_count as u64,
3942 digest,
3943 digest_len,
3944 signature,
3945 signature_len,
3946 )
3947 };
3948
3949 res = syscall_res as TEE_Result;
3951 if res != TEE_SUCCESS && res != TEE_ERROR_SIGNATURE_INVALID {
3952 TEE_Panic(res as u32);
3953 }
3954
3955 res
3956}
3957
3958#[unsafe(no_mangle)]
3966pub extern "C" fn TEE_DeriveKey(
3967 operation: *mut TEE_OperationHandle,
3968 params: *const TEE_Attribute,
3969 param_count: u32,
3970 derived_key: TEE_ObjectHandle,
3971) {
3972 if operation.is_null() || derived_key.is_null() {
3974 TEE_Panic(0);
3975 return;
3976 }
3977
3978 if !params.is_null() && param_count > 0 {
3980 if cfg!(feature = "strict_annotation_checks") {
3981 let check_res = TEE_CheckMemoryAccessRights(
3982 TEE_MEMORY_ACCESS_READ,
3983 params as *mut core::ffi::c_void,
3984 (param_count as usize) * std::mem::size_of::<TEE_Attribute>(),
3985 );
3986 if check_res != 0 {
3987 eprintln!("[in] params: error {:#010x}", check_res);
3988 TEE_Panic(0);
3989 return;
3990 }
3991 }
3992 }
3993
3994 let op_handle = unsafe { &*operation };
3996
3997 if TEE_ALG_GET_CLASS(op_handle.info.algorithm) != TEE_OPERATION_KEY_DERIVATION {
3999 TEE_Panic(0);
4000 return;
4001 }
4002
4003 if op_handle.info.operationClass != TEE_OPERATION_KEY_DERIVATION {
4005 TEE_Panic(0);
4006 return;
4007 }
4008
4009 if op_handle.key1.is_null() {
4010 TEE_Panic(0);
4011 return;
4012 }
4013
4014 if op_handle.info.mode != TEE_MODE_DERIVE {
4015 TEE_Panic(0);
4016 return;
4017 }
4018
4019 if (op_handle.info.handleState & TEE_HANDLE_FLAG_KEY_SET) == 0 {
4020 TEE_Panic(0);
4021 return;
4022 }
4023
4024 let mut key_info = crate::utee_types::utee_object_info::default();
4026
4027 let res = unsafe { _utee_cryp_obj_get_info(derived_key as u64, &mut key_info) };
4028 if res != TEE_SUCCESS as usize {
4029 TEE_Panic(res as u32);
4030 return;
4031 }
4032
4033 if key_info.obj_type != TEE_TYPE_GENERIC_SECRET {
4035 TEE_Panic(0);
4036 return;
4037 }
4038
4039 if (key_info.handle_flags & TEE_HANDLE_FLAG_INITIALIZED) != 0 {
4040 TEE_Panic(0);
4041 return;
4042 }
4043
4044 let mut ua = Vec::with_capacity(param_count as usize);
4046 ua.resize(
4047 param_count as usize,
4048 crate::utee_types::utee_attribute::default(),
4049 );
4050 unsafe {
4051 __utee_from_attr(ua.as_mut_ptr(), params, param_count);
4052 }
4053
4054 let res = unsafe {
4056 _utee_cryp_derive_key(
4057 op_handle.state as u64,
4058 ua.as_ptr(),
4059 param_count as u64,
4060 derived_key as u64,
4061 )
4062 };
4063
4064 if res != TEE_SUCCESS as usize {
4065 TEE_Panic(res as u32);
4066 }
4067}
4068
4069#[unsafe(no_mangle)]
4075pub extern "C" fn TEE_GenerateRandom(
4076 random_buffer: *mut core::ffi::c_void,
4077 random_buffer_len: usize,
4078) {
4079 if random_buffer.is_null() && random_buffer_len > 0 {
4081 TEE_Panic(TEE_ERROR_BAD_PARAMETERS as u32);
4082 return;
4083 }
4084
4085 let res = unsafe { _utee_cryp_random_number_generate(random_buffer, random_buffer_len) };
4087
4088 if res != TEE_SUCCESS as usize {
4089 TEE_Panic(res as u32);
4090 }
4091}
4092
4093#[unsafe(no_mangle)]
4103pub extern "C" fn TEE_IsAlgorithmSupported(alg: u32, element: u32) -> TEE_Result {
4104 use crate::tee_api_defines::*;
4105
4106 if alg == TEE_ALG_AES_ECB_NOPAD {
4108 if element == TEE_CRYPTO_ELEMENT_NONE {
4109 return TEE_SUCCESS;
4110 }
4111 }
4112
4113 if alg == TEE_ALG_AES_CBC_NOPAD {
4114 if element == TEE_CRYPTO_ELEMENT_NONE {
4115 return TEE_SUCCESS;
4116 }
4117 }
4118
4119 if alg == TEE_ALG_AES_CTR {
4120 if element == TEE_CRYPTO_ELEMENT_NONE {
4121 return TEE_SUCCESS;
4122 }
4123 }
4124
4125 if alg == TEE_ALG_AES_CTS {
4126 if element == TEE_CRYPTO_ELEMENT_NONE {
4127 return TEE_SUCCESS;
4128 }
4129 }
4130
4131 if alg == TEE_ALG_AES_XTS {
4132 if element == TEE_CRYPTO_ELEMENT_NONE {
4133 return TEE_SUCCESS;
4134 }
4135 }
4136
4137 if alg == TEE_ALG_AES_CBC_MAC_NOPAD || alg == TEE_ALG_AES_CBC_MAC_PKCS5 {
4138 if element == TEE_CRYPTO_ELEMENT_NONE {
4139 return TEE_SUCCESS;
4140 }
4141 }
4142
4143 if alg == TEE_ALG_AES_CMAC {
4144 if element == TEE_CRYPTO_ELEMENT_NONE {
4145 return TEE_SUCCESS;
4146 }
4147 }
4148
4149 if alg == TEE_ALG_AES_CCM {
4150 if element == TEE_CRYPTO_ELEMENT_NONE {
4151 return TEE_SUCCESS;
4152 }
4153 }
4154
4155 if alg == TEE_ALG_AES_GCM {
4156 if element == TEE_CRYPTO_ELEMENT_NONE {
4157 return TEE_SUCCESS;
4158 }
4159 }
4160
4161 if alg == TEE_ALG_DES_ECB_NOPAD || alg == TEE_ALG_DES3_ECB_NOPAD {
4163 if element == TEE_CRYPTO_ELEMENT_NONE {
4164 return TEE_SUCCESS;
4165 }
4166 }
4167
4168 if alg == TEE_ALG_DES_CBC_NOPAD || alg == TEE_ALG_DES3_CBC_NOPAD {
4169 if element == TEE_CRYPTO_ELEMENT_NONE {
4170 return TEE_SUCCESS;
4171 }
4172 }
4173
4174 if alg == TEE_ALG_DES_CBC_MAC_NOPAD
4175 || alg == TEE_ALG_DES_CBC_MAC_PKCS5
4176 || alg == TEE_ALG_DES3_CBC_MAC_NOPAD
4177 || alg == TEE_ALG_DES3_CBC_MAC_PKCS5
4178 {
4179 if element == TEE_CRYPTO_ELEMENT_NONE {
4180 return TEE_SUCCESS;
4181 }
4182 }
4183
4184 if alg == TEE_ALG_MD5 {
4186 if element == TEE_CRYPTO_ELEMENT_NONE {
4187 return TEE_SUCCESS;
4188 }
4189 }
4190
4191 if alg == TEE_ALG_SHA1 {
4193 if element == TEE_CRYPTO_ELEMENT_NONE {
4194 return TEE_SUCCESS;
4195 }
4196 }
4197
4198 if alg == TEE_ALG_SHA224 {
4200 if element == TEE_CRYPTO_ELEMENT_NONE {
4201 return TEE_SUCCESS;
4202 }
4203 }
4204
4205 if alg == TEE_ALG_SHA256 {
4207 if element == TEE_CRYPTO_ELEMENT_NONE {
4208 return TEE_SUCCESS;
4209 }
4210 }
4211
4212 if alg == TEE_ALG_SHA384 {
4214 if element == TEE_CRYPTO_ELEMENT_NONE {
4215 return TEE_SUCCESS;
4216 }
4217 }
4218
4219 if alg == TEE_ALG_SHA512 {
4221 if element == TEE_CRYPTO_ELEMENT_NONE {
4222 return TEE_SUCCESS;
4223 }
4224 }
4225
4226 if alg == TEE_ALG_MD5SHA1 {
4228 if element == TEE_CRYPTO_ELEMENT_NONE {
4229 return TEE_SUCCESS;
4230 }
4231 }
4232
4233 if alg == TEE_ALG_HMAC_MD5 {
4235 if element == TEE_CRYPTO_ELEMENT_NONE {
4236 return TEE_SUCCESS;
4237 }
4238 }
4239
4240 if alg == TEE_ALG_HMAC_SHA1 {
4241 if element == TEE_CRYPTO_ELEMENT_NONE {
4242 return TEE_SUCCESS;
4243 }
4244 }
4245
4246 if alg == TEE_ALG_HMAC_SHA224 {
4247 if element == TEE_CRYPTO_ELEMENT_NONE {
4248 return TEE_SUCCESS;
4249 }
4250 }
4251
4252 if alg == TEE_ALG_HMAC_SHA256 {
4253 if element == TEE_CRYPTO_ELEMENT_NONE {
4254 return TEE_SUCCESS;
4255 }
4256 }
4257
4258 if alg == TEE_ALG_HMAC_SHA384 {
4259 if element == TEE_CRYPTO_ELEMENT_NONE {
4260 return TEE_SUCCESS;
4261 }
4262 }
4263
4264 if alg == TEE_ALG_HMAC_SHA512 {
4265 if element == TEE_CRYPTO_ELEMENT_NONE {
4266 return TEE_SUCCESS;
4267 }
4268 }
4269
4270 if alg == TEE_ALG_HMAC_SM3 {
4271 if element == TEE_CRYPTO_ELEMENT_NONE {
4272 return TEE_SUCCESS;
4273 }
4274 }
4275
4276 if alg == TEE_ALG_SM3 {
4278 if element == TEE_CRYPTO_ELEMENT_NONE {
4279 return TEE_SUCCESS;
4280 }
4281 }
4282
4283 if alg == TEE_ALG_SM4_ECB_NOPAD {
4285 if element == TEE_CRYPTO_ELEMENT_NONE {
4286 return TEE_SUCCESS;
4287 }
4288 }
4289
4290 if alg == TEE_ALG_SM4_CBC_NOPAD {
4291 if element == TEE_CRYPTO_ELEMENT_NONE {
4292 return TEE_SUCCESS;
4293 }
4294 }
4295
4296 if alg == TEE_ALG_SM4_CTR {
4297 if element == TEE_CRYPTO_ELEMENT_NONE {
4298 return TEE_SUCCESS;
4299 }
4300 }
4301
4302 if alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5 {
4304 if element == TEE_CRYPTO_ELEMENT_NONE {
4305 return TEE_SUCCESS;
4306 }
4307 }
4308
4309 if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA1
4310 || alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA1
4311 || alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA1
4312 {
4313 if element == TEE_CRYPTO_ELEMENT_NONE {
4314 return TEE_SUCCESS;
4315 }
4316 }
4317
4318 if alg == TEE_ALG_RSASSA_PKCS1_V1_5_MD5SHA1 {
4319 if element == TEE_CRYPTO_ELEMENT_NONE {
4320 return TEE_SUCCESS;
4321 }
4322 }
4323
4324 if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA224
4325 || alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA224
4326 || alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA224
4327 {
4328 if element == TEE_CRYPTO_ELEMENT_NONE {
4329 return TEE_SUCCESS;
4330 }
4331 }
4332
4333 if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA256
4334 || alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256
4335 || alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA256
4336 {
4337 if element == TEE_CRYPTO_ELEMENT_NONE {
4338 return TEE_SUCCESS;
4339 }
4340 }
4341
4342 if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA384
4343 || alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA384
4344 || alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA384
4345 {
4346 if element == TEE_CRYPTO_ELEMENT_NONE {
4347 return TEE_SUCCESS;
4348 }
4349 }
4350
4351 if alg == TEE_ALG_RSASSA_PKCS1_V1_5_SHA512
4352 || alg == TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA512
4353 || alg == TEE_ALG_RSAES_PKCS1_OAEP_MGF1_SHA512
4354 {
4355 if element == TEE_CRYPTO_ELEMENT_NONE {
4356 return TEE_SUCCESS;
4357 }
4358 }
4359
4360 if alg == TEE_ALG_RSA_NOPAD {
4361 if element == TEE_CRYPTO_ELEMENT_NONE {
4362 return TEE_SUCCESS;
4363 }
4364 }
4365
4366 if alg == TEE_ALG_DSA_SHA1 {
4368 if element == TEE_CRYPTO_ELEMENT_NONE {
4369 return TEE_SUCCESS;
4370 }
4371 }
4372
4373 if alg == TEE_ALG_DSA_SHA224 {
4374 if element == TEE_CRYPTO_ELEMENT_NONE {
4375 return TEE_SUCCESS;
4376 }
4377 }
4378
4379 if alg == TEE_ALG_DSA_SHA256 {
4380 if element == TEE_CRYPTO_ELEMENT_NONE {
4381 return TEE_SUCCESS;
4382 }
4383 }
4384
4385 if alg == TEE_ALG_DH_DERIVE_SHARED_SECRET {
4387 if element == TEE_CRYPTO_ELEMENT_NONE {
4388 return TEE_SUCCESS;
4389 }
4390 }
4391
4392 if (alg == TEE_ALG_ECDH_P192
4394 || alg == TEE_ALG_ECDSA_P192
4395 || alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
4396 && element == TEE_ECC_CURVE_NIST_P192
4397 {
4398 return TEE_SUCCESS;
4399 }
4400
4401 if (alg == TEE_ALG_ECDH_P224
4402 || alg == TEE_ALG_ECDSA_P224
4403 || alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
4404 && element == TEE_ECC_CURVE_NIST_P224
4405 {
4406 return TEE_SUCCESS;
4407 }
4408
4409 if (alg == TEE_ALG_ECDH_P256
4410 || alg == TEE_ALG_ECDSA_P256
4411 || alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
4412 && element == TEE_ECC_CURVE_NIST_P256
4413 {
4414 return TEE_SUCCESS;
4415 }
4416
4417 if (alg == TEE_ALG_ECDH_P384
4418 || alg == TEE_ALG_ECDSA_P384
4419 || alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
4420 && element == TEE_ECC_CURVE_NIST_P384
4421 {
4422 return TEE_SUCCESS;
4423 }
4424
4425 if (alg == TEE_ALG_ECDH_P521
4426 || alg == TEE_ALG_ECDSA_P521
4427 || alg == TEE_ALG_DH_DERIVE_SHARED_SECRET)
4428 && element == TEE_ECC_CURVE_NIST_P521
4429 {
4430 return TEE_SUCCESS;
4431 }
4432
4433 if alg == TEE_ALG_SM2_DSA_SM3 && element == TEE_ECC_CURVE_SM2 {
4435 return TEE_SUCCESS;
4436 }
4437
4438 if alg == TEE_ALG_SM2_KEP && element == TEE_ECC_CURVE_SM2 {
4440 return TEE_SUCCESS;
4441 }
4442
4443 if alg == TEE_ALG_SM2_PKE && element == TEE_ECC_CURVE_SM2 {
4445 return TEE_SUCCESS;
4446 }
4447
4448 TEE_ERROR_NOT_SUPPORTED
4449}
4450
4451pub const SM2_DIGEST_LENGTH: usize = 32;
4455pub const SM2_PUBLIC_KEY_LENGTH: usize = 64;
4456pub const SM2_DEFAULT_USER_ID: &[u8] = b"1234567812345678";
4458
4459const SM2_MAX_USER_ID_LEN: usize = 1 << 13;
4460
4461const SM2P256V1_A: [u8; 32] = [
4462 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
4463 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
4464];
4465const SM2P256V1_B: [u8; 32] = [
4466 0x28, 0xE9, 0xFA, 0x9E, 0x9D, 0x9F, 0x5E, 0x34, 0x4D, 0x5A, 0x9E, 0x4B, 0xCF, 0x65, 0x09, 0xA7,
4467 0xF3, 0x97, 0x89, 0xF5, 0x15, 0xAB, 0x8F, 0x92, 0xDD, 0xBC, 0xBD, 0x41, 0x4D, 0x94, 0x0E, 0x93,
4468];
4469const SM2P256V1_GX: [u8; 32] = [
4470 0x32, 0xC4, 0xAE, 0x2C, 0x1F, 0x19, 0x81, 0x19, 0x5F, 0x99, 0x04, 0x46, 0x6A, 0x39, 0xC9, 0x94,
4471 0x8F, 0xE3, 0x0B, 0xBF, 0xF2, 0x66, 0x0B, 0xE1, 0x71, 0x5A, 0x45, 0x89, 0x33, 0x4C, 0x74, 0xC7,
4472];
4473const SM2P256V1_GY: [u8; 32] = [
4474 0xBC, 0x37, 0x36, 0xA2, 0xF4, 0xF6, 0x77, 0x9C, 0x59, 0xBD, 0xCE, 0xE3, 0x6B, 0x69, 0x21, 0x53,
4475 0xD0, 0xA9, 0x87, 0x7C, 0xC6, 0x2A, 0x47, 0x40, 0x02, 0xDF, 0x32, 0xE5, 0x21, 0x39, 0xF0, 0xA0,
4476];
4477
4478fn sm2_resolve_user_id(user_id: Option<&[u8]>) -> Result<&[u8], TEE_Result> {
4479 match user_id {
4480 None | Some([]) => Ok(SM2_DEFAULT_USER_ID),
4481 Some(id) if id.len() > SM2_MAX_USER_ID_LEN => Err(TEE_ERROR_BAD_PARAMETERS),
4482 Some(id) => Ok(id),
4483 }
4484}
4485
4486fn sm2_id_bit_length(id_len: usize) -> [u8; 2] {
4487 let bits = id_len << 3;
4488 [((bits >> 8) & 0xFF) as u8, (bits & 0xFF) as u8]
4489}
4490
4491fn sm2_sm3_finish(md: Md, out: &mut [u8; SM2_DIGEST_LENGTH]) -> TEE_Result {
4492 match md.finish(out.as_mut_slice()) {
4493 Ok(_) => TEE_SUCCESS,
4494 Err(_) => TEE_ERROR_GENERIC,
4495 }
4496}
4497
4498fn sm2_tee_check(res: TEE_Result) -> Result<(), TEE_Result> {
4499 if res == TEE_SUCCESS { Ok(()) } else { Err(res) }
4500}
4501
4502fn sm2_sm3_new() -> Result<Md, TEE_Result> {
4503 Md::new(MdType::SM3).map_err(|_| TEE_ERROR_GENERIC)
4504}
4505
4506pub fn sm2_hash_z(
4508 user_id: Option<&[u8]>,
4509 pubkey: &[u8; SM2_PUBLIC_KEY_LENGTH],
4510) -> Result<[u8; SM2_DIGEST_LENGTH], TEE_Result> {
4511 let user_id = sm2_resolve_user_id(user_id)?;
4512 let id_bit_len = sm2_id_bit_length(user_id.len());
4513
4514 let mut md = sm2_sm3_new()?;
4515 md.update(&id_bit_len).map_err(|_| TEE_ERROR_GENERIC)?;
4516 md.update(user_id).map_err(|_| TEE_ERROR_GENERIC)?;
4517 md.update(&SM2P256V1_A).map_err(|_| TEE_ERROR_GENERIC)?;
4518 md.update(&SM2P256V1_B).map_err(|_| TEE_ERROR_GENERIC)?;
4519 md.update(&SM2P256V1_GX).map_err(|_| TEE_ERROR_GENERIC)?;
4520 md.update(&SM2P256V1_GY).map_err(|_| TEE_ERROR_GENERIC)?;
4521 md.update(pubkey.as_slice())
4522 .map_err(|_| TEE_ERROR_GENERIC)?;
4523
4524 let mut z = [0u8; SM2_DIGEST_LENGTH];
4525 sm2_tee_check(sm2_sm3_finish(md, &mut z))?;
4526 Ok(z)
4527}
4528
4529pub fn sm2_hash_e(
4531 z: &[u8; SM2_DIGEST_LENGTH],
4532 msg: &[u8],
4533) -> Result<[u8; SM2_DIGEST_LENGTH], TEE_Result> {
4534 let mut md = sm2_sm3_new()?;
4535 md.update(z).map_err(|_| TEE_ERROR_GENERIC)?;
4536 md.update(msg).map_err(|_| TEE_ERROR_GENERIC)?;
4537
4538 let mut e = [0u8; SM2_DIGEST_LENGTH];
4539 sm2_tee_check(sm2_sm3_finish(md, &mut e))?;
4540 Ok(e)
4541}
4542
4543pub fn sm2_compute_sign_digest(
4545 user_id: Option<&[u8]>,
4546 msg: &[u8],
4547 pubkey: &[u8; SM2_PUBLIC_KEY_LENGTH],
4548) -> Result<[u8; SM2_DIGEST_LENGTH], TEE_Result> {
4549 let z = sm2_hash_z(user_id, pubkey)?;
4550 sm2_hash_e(&z, msg)
4551}
4552
4553#[unsafe(no_mangle)]
4557pub extern "C" fn sm2_sign_digest(
4558 user_id: *const u8,
4559 id_len: usize,
4560 msg: *const u8,
4561 msg_len: u32,
4562 pubkey: *const u8,
4563 e: *mut u8,
4564) -> TEE_Result {
4565 if msg.is_null() || pubkey.is_null() || e.is_null() {
4566 return TEE_ERROR_BAD_PARAMETERS;
4567 }
4568
4569 let user_id = if user_id.is_null() || id_len == 0 {
4570 None
4571 } else {
4572 Some(unsafe { core::slice::from_raw_parts(user_id, id_len) })
4573 };
4574
4575 let msg = unsafe { core::slice::from_raw_parts(msg, msg_len as usize) };
4576 let pubkey_slice = unsafe { core::slice::from_raw_parts(pubkey, SM2_PUBLIC_KEY_LENGTH) };
4577 let Ok(pubkey_arr) = pubkey_slice.try_into() else {
4578 return TEE_ERROR_BAD_PARAMETERS;
4579 };
4580
4581 match sm2_compute_sign_digest(user_id, msg, pubkey_arr) {
4582 Ok(digest) => {
4583 unsafe {
4584 core::ptr::copy_nonoverlapping(digest.as_ptr(), e, SM2_DIGEST_LENGTH);
4585 }
4586 TEE_SUCCESS
4587 }
4588 Err(err) => err,
4589 }
4590}
4591
4592#[cfg(test)]
4593mod sm2_tests {
4594 use super::*;
4595
4596 const TEST_PUBKEY: [u8; SM2_PUBLIC_KEY_LENGTH] = [
4597 0x09, 0xF9, 0xDF, 0x31, 0x1E, 0x54, 0x21, 0xA1, 0x50, 0xDD, 0x7D, 0x16, 0x1E, 0x4B, 0xC5,
4598 0xC6, 0x72, 0x17, 0x9F, 0xAD, 0x18, 0x33, 0xFC, 0x07, 0x6B, 0xB0, 0x8F, 0xF3, 0x56, 0xF3,
4599 0x50, 0x20, 0xCC, 0xEA, 0x49, 0x0C, 0xE2, 0x67, 0x75, 0xA5, 0x2D, 0xC6, 0xEA, 0x71, 0x8C,
4600 0xC1, 0xAA, 0x60, 0x0A, 0xED, 0x05, 0xFB, 0xF3, 0x5E, 0x08, 0x4A, 0x66, 0x32, 0xF6, 0x07,
4601 0x2D, 0xA9, 0xAD, 0x13,
4602 ];
4603 const TEST_Z: [u8; SM2_DIGEST_LENGTH] = [
4604 0xB2, 0xE1, 0x4C, 0x5C, 0x79, 0xC6, 0xDF, 0x5B, 0x85, 0xF4, 0xFE, 0x7E, 0xD8, 0xDB, 0x7A,
4605 0x26, 0x2B, 0x9D, 0xA7, 0xE0, 0x7C, 0xCB, 0x0E, 0xA9, 0xF4, 0x74, 0x7B, 0x8C, 0xCD, 0xA8,
4606 0xA4, 0xF3,
4607 ];
4608 const TEST_E: [u8; SM2_DIGEST_LENGTH] = [
4609 0xF0, 0xB4, 0x3E, 0x94, 0xBA, 0x45, 0xAC, 0xCA, 0xAC, 0xE6, 0x92, 0xED, 0x53, 0x43, 0x82,
4610 0xEB, 0x17, 0xE6, 0xAB, 0x5A, 0x19, 0xCE, 0x7B, 0x31, 0xF4, 0x48, 0x6F, 0xDF, 0xC0, 0xD2,
4611 0x86, 0x40,
4612 ];
4613
4614 #[test]
4615 fn sm2_hash_z_matches_mbedtls_vector() {
4616 let z = sm2_hash_z(None, &TEST_PUBKEY).unwrap();
4617 assert_eq!(z, TEST_Z);
4618 }
4619
4620 #[test]
4621 fn sm2_sign_digest_matches_mbedtls_vector() {
4622 let msg = b"message digest";
4623 let e = sm2_compute_sign_digest(None, msg, &TEST_PUBKEY).unwrap();
4624 assert_eq!(e, TEST_E);
4625 }
4626}