1use crate::tee_api_defines::{TEE_ERROR_OVERFLOW, TEE_SUCCESS};
11use crate::tee_api_types::{TEE_BigInt, TEE_BigIntFMM, TEE_BigIntFMMContext, TEE_Result};
12use mbedtls::bignum::Mpi;
13use mbedtls::error::Error;
14use mbedtls::rng::RngCallback;
15pub use mbedtls_sys_auto::mpi_sint;
16use std::ops::ShrAssign;
17
18use mbedtls_sys_auto as mbedtls_sys;
20
21#[repr(C)]
22struct BigintHdr {
23 pub sign: i32, pub alloc_size: u16, pub nblimbs: u16, }
27
28pub const BIGINT_HDR_SIZE_IN_U32: usize = 2;
29
30const CFG_TA_BIGNUM_MAX_BITS: usize = 4096;
32pub trait TeeBigIntExt {
36 unsafe fn to_teebigint(&self, bigint: *mut TEE_BigInt, alloc_size: usize) -> Result<(), Error>;
38
39 unsafe fn from_teebigint(bigint: *const TEE_BigInt) -> Result<Self, Error>
41 where
42 Self: Sized;
43}
44
45impl TeeBigIntExt for Mpi {
47 unsafe fn to_teebigint(&self, bigint: *mut TEE_BigInt, alloc_size: usize) -> Result<(), Error> {
51 if bigint.is_null() {
53 return Err(mbedtls::error::codes::MpiBadInputData.into());
54 }
55
56 let mpi_limbs_count = {
58 let handle: *const mbedtls_sys::mpi = self.into();
59 unsafe {
60 let mut limbs_count = (*handle).n;
61 while limbs_count > 0 && self.get_limb(limbs_count - 1) == 0 {
63 limbs_count -= 1;
64 }
65 limbs_count
66 }
67 };
68
69 let mut tee_limbs_count = 0;
72 for i in 0..mpi_limbs_count {
73 let limb = self.get_limb(i);
74 if i == mpi_limbs_count - 1 {
75 if limb == 0 {
77 continue; } else if limb <= 0xFFFFFFFF {
79 tee_limbs_count += 1;
81 } else {
82 tee_limbs_count += 2;
84 }
85 } else {
86 tee_limbs_count += 2;
88 }
89 }
90
91 if alloc_size < tee_limbs_count {
93 return Err(mbedtls::error::codes::MpiBufferTooSmall.into());
94 }
95
96 unsafe {
98 let header = bigint as *mut BigintHdr;
100
101 let handle: *const mbedtls_sys::mpi = self.into();
103 (*header).sign = (*handle).s; (*header).alloc_size = alloc_size as u16; (*header).nblimbs = tee_limbs_count as u16; let mut tee_index = 0;
109 for i in 0..mpi_limbs_count {
110 let limb = self.get_limb(i);
111
112 let low_ptr = bigint.add(2 + tee_index) as *mut u32;
114 *low_ptr = (limb & 0xFFFFFFFF) as u32;
115 tee_index += 1;
116
117 if i < mpi_limbs_count - 1 || limb > 0xFFFFFFFF {
119 let high_ptr = bigint.add(2 + tee_index) as *mut u32;
120 *high_ptr = ((limb >> 32) & 0xFFFFFFFF) as u32;
121 tee_index += 1;
122 }
123 }
124 }
125
126 Ok(())
127 }
128
129 unsafe fn from_teebigint(bigint: *const TEE_BigInt) -> Result<Self, Error> {
133 if bigint.is_null() {
135 return Mpi::new(0);
136 }
137
138 let (sign, nblimbs) = unsafe {
140 let header = bigint as *const BigintHdr;
141 ((*header).sign, (*header).nblimbs as usize)
142 };
143
144 if nblimbs == 0 {
146 return Mpi::new(0);
147 }
148
149 let mut data_vec = Vec::with_capacity((nblimbs + 1) / 2);
153 let mut i = 0;
154 while i < nblimbs {
155 let low = unsafe {
156 let low_ptr = bigint.add(2 + i) as *const u32;
157 if low_ptr.is_null() { 0 } else { *low_ptr }
158 };
159
160 if i + 1 < nblimbs {
161 let high = unsafe {
163 let high_ptr = bigint.add(2 + i + 1) as *const u32;
164 if high_ptr.is_null() { 0 } else { *high_ptr }
165 };
166
167 let combined = ((high as u64) << 32) | (low as u64);
171 data_vec.push(combined as mbedtls_sys::mpi_uint);
172 i += 2;
173 } else {
174 data_vec.push(low as mbedtls_sys::mpi_uint);
176 i += 1;
177 }
178 }
179
180 let trimmed_data = {
182 let mut len = data_vec.len();
183 while len > 0 && data_vec[len - 1] == 0 {
184 len -= 1;
185 }
186 &data_vec[..len]
187 };
188
189 if trimmed_data.is_empty() {
191 return Mpi::new(0);
192 }
193
194 let mut mpi = Mpi::new(0)?;
196
197 unsafe {
199 let handle: *mut mbedtls_sys::mpi = (&mut mpi).into();
201 let result = mbedtls_sys::mpi_grow(handle, trimmed_data.len());
202 if result != 0 {
203 return Err(mbedtls::error::codes::MpiBadInputData.into());
204 }
205
206 (*handle).s = sign;
208
209 let dst_ptr = (*handle).p;
211 std::ptr::copy_nonoverlapping(trimmed_data.as_ptr(), dst_ptr, trimmed_data.len());
212 }
213
214 Ok(mpi)
215 }
216}
217
218trait MpiExt {
220 fn get_limb(&self, n: usize) -> mbedtls_sys::mpi_uint;
221}
222
223impl MpiExt for Mpi {
224 fn get_limb(&self, n: usize) -> mbedtls_sys::mpi_uint {
225 let handle: *const mbedtls_sys::mpi = self.into();
226 let n_limbs = unsafe { (*handle).n };
227 if n < n_limbs {
228 unsafe { *(*handle).p.offset(n as isize) }
229 } else {
230 0
232 }
233 }
234}
235
236#[unsafe(no_mangle)]
242pub extern "C" fn TEE_BigIntInit(big_int: *mut TEE_BigInt, len: usize) {
243 if len > CFG_TA_BIGNUM_MAX_BITS / 4 {
245 panic!("Too large bigint");
246 }
247 let alloc_size = (len - BIGINT_HDR_SIZE_IN_U32) as u16;
248
249 unsafe {
251 core::ptr::write_bytes(big_int as *mut u8, 0, len * 4);
252 let hdr = big_int as *mut BigintHdr;
253 (*hdr).sign = 1;
254 (*hdr).alloc_size = alloc_size;
255 (*hdr).nblimbs = 0;
256 }
257}
258
259#[unsafe(no_mangle)]
270pub extern "C" fn TEE_BigIntConvertFromOctetString(
271 dest: *mut TEE_BigInt,
272 buffer: *const u8,
273 buffer_len: usize,
274 sign: i32,
275) -> TEE_Result {
276 let buffer_slice = unsafe { core::slice::from_raw_parts(buffer, buffer_len) };
278
279 match Mpi::from_binary(buffer_slice) {
280 Ok(mut mpi) => {
281 if sign < 0 {
283 match Mpi::new(-1) {
284 Ok(neg_one) => {
285 unsafe {
286 let result = mbedtls_sys::mpi_mul_mpi(
288 (&mut mpi).into(),
289 (&mpi).into(),
290 (&neg_one).into(),
291 );
292 if result != 0 {
293 return TEE_ERROR_OVERFLOW;
294 }
295 }
296 }
297 Err(_) => return TEE_ERROR_OVERFLOW,
298 }
299 }
300
301 unsafe {
303 let hdr = dest as *mut BigintHdr;
304 let alloc_size = (*hdr).alloc_size as usize;
305
306 match mpi.to_teebigint(dest, alloc_size) {
308 Ok(()) => TEE_SUCCESS,
309 Err(_) => TEE_ERROR_OVERFLOW,
310 }
311 }
312 }
313 Err(_) => TEE_ERROR_OVERFLOW,
314 }
315}
316
317#[unsafe(no_mangle)]
327pub extern "C" fn TEE_BigIntConvertToOctetString(
328 buffer: *mut u8,
329 buffer_len: *mut usize,
330 big_int: *const TEE_BigInt,
331) -> TEE_Result {
332 if buffer_len.is_null() || big_int.is_null() {
334 return TEE_ERROR_OVERFLOW; }
336
337 let mpi = match unsafe { Mpi::from_teebigint(big_int) } {
339 Ok(mpi) => mpi,
340 Err(_) => return TEE_ERROR_OVERFLOW,
341 };
342
343 let sz = match mpi.byte_length() {
345 Ok(len) => len,
346 Err(_) => return TEE_ERROR_OVERFLOW,
347 };
348
349 let provided_buffer_len = unsafe { *buffer_len };
351
352 if sz <= provided_buffer_len {
353 if !buffer.is_null() {
354 match mpi.to_binary() {
356 Ok(binary_data) => {
357 unsafe {
359 core::ptr::copy_nonoverlapping(
360 binary_data.as_ptr(),
361 buffer,
362 binary_data.len(),
363 );
364 }
365 }
366 Err(_) => return TEE_ERROR_OVERFLOW,
367 }
368 }
369 } else {
370 unsafe { *buffer_len = sz };
372 return TEE_ERROR_OVERFLOW; }
374
375 unsafe { *buffer_len = sz };
377
378 TEE_SUCCESS
379}
380
381#[unsafe(no_mangle)]
387pub extern "C" fn TEE_BigIntConvertFromS32(dest: *mut TEE_BigInt, short_val: i32) {
388 unsafe {
389 let hdr = dest as *mut BigintHdr;
390
391 if short_val < 0 {
393 (*hdr).sign = -1;
394 } else {
395 (*hdr).sign = 1;
396 }
397
398 let abs_val = if short_val < 0 {
400 -(short_val as i64) as u32
401 } else {
402 short_val as u32
403 };
404
405 let data_ptr = dest.add(2) as *mut u32;
407 let alloc_size = (*hdr).alloc_size as usize;
408 for i in 0..alloc_size {
409 *data_ptr.add(i) = 0;
410 }
411
412 if alloc_size > 0 {
414 *data_ptr = abs_val;
415 (*hdr).nblimbs = if abs_val == 0 { 0 } else { 1 };
416 } else {
417 (*hdr).nblimbs = 0;
418 }
419 }
420}
421
422#[unsafe(no_mangle)]
431pub extern "C" fn TEE_BigIntConvertToS32(dest: *mut i32, src: *const TEE_BigInt) -> TEE_Result {
432 let mpi = match unsafe { Mpi::from_teebigint(src) } {
434 Ok(mpi) => mpi,
435 Err(_) => return TEE_ERROR_OVERFLOW,
436 };
437
438 match mpi.to_binary() {
440 Ok(binary_data) => {
441 if binary_data.len() > 4 {
443 return TEE_ERROR_OVERFLOW;
444 }
445
446 let mut v: u32 = 0;
448 for &byte in &binary_data {
449 v = (v << 8) | byte as u32;
450 }
451
452 if mpi.sign() == mbedtls::bignum::Sign::Positive {
454 if v > i32::MAX as u32 {
456 return TEE_ERROR_OVERFLOW;
457 }
458 unsafe {
459 *dest = v as i32;
460 }
461 } else {
462 if v > (i32::MAX as u32 + 1) {
466 return TEE_ERROR_OVERFLOW;
467 }
468 unsafe {
469 *dest = if v as i32 == i32::MIN {
470 i32::MIN
471 } else {
472 -(v as i32)
473 };
474 }
475 }
476
477 TEE_SUCCESS
478 }
479 Err(_) => TEE_ERROR_OVERFLOW,
480 }
481}
482
483#[unsafe(no_mangle)]
492pub extern "C" fn TEE_BigIntCmp(op1: *const TEE_BigInt, op2: *const TEE_BigInt) -> i32 {
493 let mpi1 = match unsafe { Mpi::from_teebigint(op1) } {
495 Ok(mpi) => mpi,
496 Err(_) => return 0, };
498
499 let mpi2 = match unsafe { Mpi::from_teebigint(op2) } {
500 Ok(mpi) => mpi,
501 Err(_) => return 0, };
503
504 match mpi1.cmp(&mpi2) {
506 std::cmp::Ordering::Less => -1,
507 std::cmp::Ordering::Equal => 0,
508 std::cmp::Ordering::Greater => 1,
509 }
510}
511
512#[unsafe(no_mangle)]
521pub extern "C" fn TEE_BigIntCmpS32(src: *const TEE_BigInt, short_val: i32) -> i32 {
522 let mpi = match unsafe { Mpi::from_teebigint(src) } {
524 Ok(mpi) => mpi,
525 Err(_) => return 0, };
527
528 let cmp_mpi = match Mpi::new(short_val as mpi_sint) {
530 Ok(mpi) => mpi,
531 Err(_) => return 0, };
533
534 match mpi.cmp(&cmp_mpi) {
536 std::cmp::Ordering::Less => -1,
537 std::cmp::Ordering::Equal => 0,
538 std::cmp::Ordering::Greater => 1,
539 }
540}
541
542#[unsafe(no_mangle)]
549pub extern "C" fn TEE_BigIntShiftRight(dest: *mut TEE_BigInt, op: *const TEE_BigInt, bits: usize) {
550 let mut temp_mpi = match unsafe { Mpi::from_teebigint(op) } {
552 Ok(mpi) => mpi,
553 Err(_) => return, };
555
556 temp_mpi.shr_assign(bits);
558
559 let dest_info = unsafe {
561 let hdr = dest as *mut BigintHdr;
562 (*hdr).alloc_size as usize
563 };
564
565 unsafe {
567 match temp_mpi.to_teebigint(dest, dest_info) {
568 Ok(_) => {
569 }
571 Err(_) => {
572 let hdr = dest as *mut BigintHdr;
574 (*hdr).sign = 0;
575 (*hdr).nblimbs = 0;
576
577 let data_ptr = dest.add(2) as *mut u32;
579 for i in 0..dest_info {
580 *data_ptr.add(i) = 0;
581 }
582 }
583 }
584 }
585}
586
587#[unsafe(no_mangle)]
596pub extern "C" fn TEE_BigIntGetBit(src: *const TEE_BigInt, bit_index: u32) -> bool {
597 let mpi = match unsafe { Mpi::from_teebigint(src) } {
599 Ok(mpi) => mpi,
600 Err(_) => return false, };
602
603 mpi.get_bit(bit_index as usize)
605}
606
607#[unsafe(no_mangle)]
615pub extern "C" fn TEE_BigIntGetBitCount(src: *const TEE_BigInt) -> u32 {
616 let mpi = match unsafe { Mpi::from_teebigint(src) } {
618 Ok(mpi) => mpi,
619 Err(_) => return 0, };
621
622 match mpi.bit_length() {
624 Ok(len) => len as u32,
625 Err(_) => 0, }
627}
628
629#[unsafe(no_mangle)]
639pub extern "C" fn TEE_BigIntSetBit(op: *mut TEE_BigInt, bit_index: u32, value: bool) -> TEE_Result {
640 let mut mpi = match unsafe { Mpi::from_teebigint(op as *const TEE_BigInt) } {
642 Ok(mpi) => mpi,
643 Err(_) => return TEE_ERROR_OVERFLOW,
644 };
645
646 match mpi.set_bit(bit_index as usize, value) {
648 Ok(()) => {
649 unsafe {
651 let hdr = op as *mut BigintHdr;
652 let alloc_size = (*hdr).alloc_size as usize;
653
654 match mpi.to_teebigint(op, alloc_size) {
655 Ok(()) => TEE_SUCCESS,
656 Err(_) => TEE_ERROR_OVERFLOW,
657 }
658 }
659 }
660 Err(_) => TEE_ERROR_OVERFLOW,
661 }
662}
663
664#[unsafe(no_mangle)]
673pub extern "C" fn TEE_BigIntAssign(dest: *mut TEE_BigInt, src: *const TEE_BigInt) -> TEE_Result {
674 if dest == src as *mut TEE_BigInt {
676 return TEE_SUCCESS;
677 }
678
679 if dest.is_null() || src.is_null() {
681 return TEE_ERROR_OVERFLOW;
682 }
683
684 unsafe {
685 let src_hdr = src as *const BigintHdr;
686 let dst_hdr = dest as *mut BigintHdr;
687
688 if (*dst_hdr).alloc_size < (*src_hdr).nblimbs {
690 return TEE_ERROR_OVERFLOW;
691 }
692
693 let src_slice = core::slice::from_raw_parts(
695 (src as *const u32).add(BIGINT_HDR_SIZE_IN_U32),
696 (*src_hdr).nblimbs as usize,
697 );
698
699 let dst_slice = core::slice::from_raw_parts_mut(
700 dest.add(BIGINT_HDR_SIZE_IN_U32),
701 (*src_hdr).nblimbs as usize,
702 );
703
704 (*dst_hdr).nblimbs = (*src_hdr).nblimbs;
706 (*dst_hdr).sign = (*src_hdr).sign;
707
708 dst_slice.copy_from_slice(src_slice);
710 }
711
712 TEE_SUCCESS
713}
714
715#[unsafe(no_mangle)]
724pub extern "C" fn TEE_BigIntAbs(dest: *mut TEE_BigInt, src: *const TEE_BigInt) -> TEE_Result {
725 let res = TEE_BigIntAssign(dest, src);
726
727 if res == TEE_SUCCESS {
728 unsafe {
729 let dst_hdr = dest as *mut BigintHdr;
730 (*dst_hdr).sign = 1; }
732 }
733
734 res
735}
736
737fn bigint_binary(
745 dest: *mut TEE_BigInt,
746 op1: *const TEE_BigInt,
747 op2: *const TEE_BigInt,
748 func: unsafe extern "C" fn(
749 *mut mbedtls_sys_auto::mpi,
750 *const mbedtls_sys_auto::mpi,
751 *const mbedtls_sys_auto::mpi,
752 ) -> i32,
753) -> TEE_Result {
754 unsafe {
755 let dst_hdr = dest as *mut BigintHdr;
757 let alloc_size = (*dst_hdr).alloc_size as usize;
758
759 let mpi_op1 = if op1 == dest as *const TEE_BigInt {
761 None } else {
763 match Mpi::from_teebigint(op1) {
764 Ok(mpi) => Some(mpi),
765 Err(_) => return TEE_ERROR_OVERFLOW,
766 }
767 };
768
769 let mpi_op2 = if op2 == dest as *const TEE_BigInt {
770 None } else if op2 == op1 {
772 mpi_op1.clone() } else {
774 match Mpi::from_teebigint(op2) {
775 Ok(mpi) => Some(mpi),
776 Err(_) => return TEE_ERROR_OVERFLOW,
777 }
778 };
779
780 let mut mpi_dest = match Mpi::from_teebigint(dest as *const TEE_BigInt) {
782 Ok(mpi) => mpi,
783 Err(_) => return TEE_ERROR_OVERFLOW,
784 };
785
786 let result = if op1 == dest as *const TEE_BigInt && op2 == dest as *const TEE_BigInt {
788 func(
790 (&mut mpi_dest).into(),
791 (&mpi_dest).into(),
792 (&mpi_dest).into(),
793 )
794 } else if op1 == dest as *const TEE_BigInt {
795 if op2 == op1 {
797 func(
799 (&mut mpi_dest).into(),
800 (&mpi_dest).into(),
801 (&mpi_dest).into(),
802 )
803 } else {
804 func(
806 (&mut mpi_dest).into(),
807 (&mpi_dest).into(),
808 mpi_op2.as_ref().unwrap().into(),
809 )
810 }
811 } else if op2 == dest as *const TEE_BigInt {
812 func(
814 (&mut mpi_dest).into(),
815 mpi_op1.as_ref().unwrap().into(),
816 (&mpi_dest).into(),
817 )
818 } else {
819 if op2 == op1 {
821 let op1_handle = mpi_op1.as_ref().unwrap().into();
823 func((&mut mpi_dest).into(), op1_handle, op1_handle)
824 } else {
825 func(
827 (&mut mpi_dest).into(),
828 mpi_op1.as_ref().unwrap().into(),
829 mpi_op2.as_ref().unwrap().into(),
830 )
831 }
832 };
833
834 if result != 0 {
835 return TEE_ERROR_OVERFLOW;
836 }
837
838 match mpi_dest.to_teebigint(dest, alloc_size) {
840 Ok(()) => TEE_SUCCESS,
841 Err(_) => TEE_ERROR_OVERFLOW,
842 }
843 }
844}
845
846fn bigint_binary_mod(
855 dest: *mut TEE_BigInt,
856 op1: *const TEE_BigInt,
857 op2: *const TEE_BigInt,
858 n: *const TEE_BigInt,
859 func: unsafe extern "C" fn(
860 *mut mbedtls_sys_auto::mpi,
861 *const mbedtls_sys_auto::mpi,
862 *const mbedtls_sys_auto::mpi,
863 ) -> i32,
864) -> TEE_Result {
865 unsafe {
866 if TEE_BigIntCmpS32(n, 2) < 0 {
868 panic!("Modulus is too short");
869 }
870
871 let dst_hdr = dest as *mut BigintHdr;
873 let alloc_size = (*dst_hdr).alloc_size as usize;
874
875 let mpi_n = match Mpi::from_teebigint(n) {
877 Ok(mpi) => mpi,
878 Err(_) => return TEE_ERROR_OVERFLOW,
879 };
880
881 let mpi_op1 = if op1 == dest as *const TEE_BigInt {
883 None } else {
885 match Mpi::from_teebigint(op1) {
886 Ok(mpi) => Some(mpi),
887 Err(_) => return TEE_ERROR_OVERFLOW,
888 }
889 };
890
891 let mpi_op2 = if op2 == dest as *const TEE_BigInt {
892 None } else if op2 == op1 {
894 mpi_op1.clone() } else {
896 match Mpi::from_teebigint(op2) {
897 Ok(mpi) => Some(mpi),
898 Err(_) => return TEE_ERROR_OVERFLOW,
899 }
900 };
901
902 let mut mpi_dest = match Mpi::from_teebigint(dest as *const TEE_BigInt) {
904 Ok(mpi) => mpi,
905 Err(_) => return TEE_ERROR_OVERFLOW,
906 };
907
908 let mut mpi_t = match Mpi::new(0) {
910 Ok(mpi) => mpi,
911 Err(_) => return TEE_ERROR_OVERFLOW,
912 };
913
914 let result = if op1 == dest as *const TEE_BigInt && op2 == dest as *const TEE_BigInt {
916 func((&mut mpi_t).into(), (&mpi_dest).into(), (&mpi_dest).into())
918 } else if op1 == dest as *const TEE_BigInt {
919 if op2 == op1 {
921 func((&mut mpi_t).into(), (&mpi_dest).into(), (&mpi_dest).into())
923 } else {
924 func(
926 (&mut mpi_t).into(),
927 (&mpi_dest).into(),
928 mpi_op2.as_ref().unwrap().into(),
929 )
930 }
931 } else if op2 == dest as *const TEE_BigInt {
932 func(
934 (&mut mpi_t).into(),
935 mpi_op1.as_ref().unwrap().into(),
936 (&mpi_dest).into(),
937 )
938 } else {
939 if op2 == op1 {
941 let op1_handle = mpi_op1.as_ref().unwrap().into();
943 func((&mut mpi_t).into(), op1_handle, op1_handle)
944 } else {
945 func(
947 (&mut mpi_t).into(),
948 mpi_op1.as_ref().unwrap().into(),
949 mpi_op2.as_ref().unwrap().into(),
950 )
951 }
952 };
953
954 if result != 0 {
955 return TEE_ERROR_OVERFLOW;
956 }
957
958 let mod_result =
960 mbedtls_sys::mpi_mod_mpi((&mut mpi_dest).into(), (&mpi_t).into(), (&mpi_n).into());
961
962 if mod_result != 0 {
963 return TEE_ERROR_OVERFLOW;
964 }
965
966 match mpi_dest.to_teebigint(dest, alloc_size) {
968 Ok(()) => TEE_SUCCESS,
969 Err(_) => TEE_ERROR_OVERFLOW,
970 }
971 }
972}
973
974#[unsafe(no_mangle)]
981pub extern "C" fn TEE_BigIntAdd(
982 dest: *mut TEE_BigInt,
983 op1: *const TEE_BigInt,
984 op2: *const TEE_BigInt,
985) {
986 let _ = bigint_binary(dest, op1, op2, mbedtls_sys_auto::mpi_add_mpi);
987}
988
989#[unsafe(no_mangle)]
996pub extern "C" fn TEE_BigIntSub(
997 dest: *mut TEE_BigInt,
998 op1: *const TEE_BigInt,
999 op2: *const TEE_BigInt,
1000) {
1001 let _ = bigint_binary(dest, op1, op2, mbedtls_sys_auto::mpi_sub_mpi);
1002}
1003
1004#[unsafe(no_mangle)]
1010pub extern "C" fn TEE_BigIntNeg(dest: *mut TEE_BigInt, src: *const TEE_BigInt) {
1011 unsafe {
1012 let dst_hdr = dest as *mut BigintHdr;
1014 let alloc_size = (*dst_hdr).alloc_size as usize;
1015
1016 let mut mpi_src = if dest == src as *mut TEE_BigInt {
1018 match Mpi::from_teebigint(src) {
1020 Ok(mpi) => mpi,
1021 Err(_) => return, }
1023 } else {
1024 match Mpi::from_teebigint(src) {
1026 Ok(mpi) => mpi,
1027 Err(_) => return, }
1029 };
1030
1031 let handle: *mut mbedtls_sys::mpi = (&mut mpi_src).into();
1034 (*handle).s *= -1;
1035
1036 let _ = mpi_src.to_teebigint(dest, alloc_size);
1038 }
1039}
1040
1041fn tee_big_int_size_in_u32(n: usize) -> usize {
1049 ((n + 31) / 32) + BIGINT_HDR_SIZE_IN_U32
1050}
1051
1052#[unsafe(no_mangle)]
1059pub extern "C" fn TEE_BigIntMul(
1060 dest: *mut TEE_BigInt,
1061 op1: *const TEE_BigInt,
1062 op2: *const TEE_BigInt,
1063) {
1064 let bs1 = TEE_BigIntGetBitCount(op1);
1066 let bs2 = TEE_BigIntGetBitCount(op2);
1067
1068 let s = tee_big_int_size_in_u32(bs1 as usize) + tee_big_int_size_in_u32(bs2 as usize);
1070
1071 let mut tmp_storage = vec![0u32; s];
1073 let tmp = tmp_storage.as_mut_ptr();
1074
1075 TEE_BigIntInit(tmp, s);
1077
1078 let _ = bigint_binary(tmp, op1, op2, mbedtls_sys_auto::mpi_mul_mpi);
1080
1081 let zero_storage = [0u32; BIGINT_HDR_SIZE_IN_U32 + 1];
1083 let zero = zero_storage.as_ptr();
1084 TEE_BigIntInit(zero as *mut TEE_BigInt, BIGINT_HDR_SIZE_IN_U32 + 1);
1085
1086 TEE_BigIntAdd(dest, tmp, zero);
1087
1088 }
1090
1091#[unsafe(no_mangle)]
1097pub extern "C" fn TEE_BigIntSquare(dest: *mut TEE_BigInt, op: *const TEE_BigInt) {
1098 TEE_BigIntMul(dest, op, op);
1100}
1101
1102#[unsafe(no_mangle)]
1110pub extern "C" fn TEE_BigIntDiv(
1111 dest_q: *mut TEE_BigInt,
1112 dest_r: *mut TEE_BigInt,
1113 op1: *const TEE_BigInt,
1114 op2: *const TEE_BigInt,
1115) {
1116 unsafe {
1117 let zero_check = Mpi::from_teebigint(op2);
1119 if let Ok(ref mpi_op2) = zero_check {
1120 let is_zero = match mpi_op2.to_binary() {
1122 Ok(binary_data) => binary_data.iter().all(|&x| x == 0),
1123 Err(_) => true, };
1125
1126 if is_zero {
1127 panic!("Division by zero");
1128 }
1129 }
1130
1131 let q_alloc_size = if !dest_q.is_null() {
1133 let q_hdr = dest_q as *mut BigintHdr;
1134 Some((*q_hdr).alloc_size as usize)
1135 } else {
1136 None
1137 };
1138
1139 let r_alloc_size = if !dest_r.is_null() {
1140 let r_hdr = dest_r as *mut BigintHdr;
1141 Some((*r_hdr).alloc_size as usize)
1142 } else {
1143 None
1144 };
1145
1146 let mpi_op1 = if op1 == dest_q || op1 == dest_r {
1148 match Mpi::from_teebigint(op1) {
1150 Ok(mpi) => mpi,
1151 Err(_) => return, }
1153 } else {
1154 match Mpi::from_teebigint(op1) {
1155 Ok(mpi) => mpi,
1156 Err(_) => return, }
1158 };
1159
1160 let mpi_op2 = if op2 == op1 {
1161 mpi_op1.clone()
1163 } else if op2 == dest_q || op2 == dest_r {
1164 match Mpi::from_teebigint(op2) {
1166 Ok(mpi) => mpi,
1167 Err(_) => return, }
1169 } else {
1170 match Mpi::from_teebigint(op2) {
1171 Ok(mpi) => mpi,
1172 Err(_) => return, }
1174 };
1175
1176 let mut mpi_dest_q = match Mpi::new(0) {
1178 Ok(mpi) => mpi,
1179 Err(_) => return, };
1181
1182 let mut mpi_dest_r = match Mpi::new(0) {
1183 Ok(mpi) => mpi,
1184 Err(_) => return, };
1186
1187 let result = mbedtls_sys::mpi_div_mpi(
1189 (&mut mpi_dest_q).into(),
1190 (&mut mpi_dest_r).into(),
1191 (&mpi_op1).into(),
1192 (&mpi_op2).into(),
1193 );
1194
1195 if result != 0 {
1196 return; }
1198
1199 if !dest_q.is_null() {
1201 let _ = mpi_dest_q.to_teebigint(dest_q, q_alloc_size.unwrap());
1202 }
1203
1204 if !dest_r.is_null() {
1205 let _ = mpi_dest_r.to_teebigint(dest_r, r_alloc_size.unwrap());
1206 }
1207 }
1208}
1209
1210#[unsafe(no_mangle)]
1217pub extern "C" fn TEE_BigIntMod(
1218 dest: *mut TEE_BigInt,
1219 op: *const TEE_BigInt,
1220 n: *const TEE_BigInt,
1221) {
1222 if TEE_BigIntCmpS32(n, 2) < 0 {
1224 panic!("Modulus is too short");
1225 }
1226
1227 let _ = bigint_binary(dest, op, n, mbedtls_sys_auto::mpi_mod_mpi);
1228}
1229
1230#[unsafe(no_mangle)]
1238pub extern "C" fn TEE_BigIntAddMod(
1239 dest: *mut TEE_BigInt,
1240 op1: *const TEE_BigInt,
1241 op2: *const TEE_BigInt,
1242 n: *const TEE_BigInt,
1243) {
1244 let _ = bigint_binary_mod(dest, op1, op2, n, mbedtls_sys_auto::mpi_add_mpi);
1245}
1246
1247#[unsafe(no_mangle)]
1255pub extern "C" fn TEE_BigIntSubMod(
1256 dest: *mut TEE_BigInt,
1257 op1: *const TEE_BigInt,
1258 op2: *const TEE_BigInt,
1259 n: *const TEE_BigInt,
1260) {
1261 let _ = bigint_binary_mod(dest, op1, op2, n, mbedtls_sys_auto::mpi_sub_mpi);
1262}
1263
1264#[unsafe(no_mangle)]
1272pub extern "C" fn TEE_BigIntMulMod(
1273 dest: *mut TEE_BigInt,
1274 op1: *const TEE_BigInt,
1275 op2: *const TEE_BigInt,
1276 n: *const TEE_BigInt,
1277) {
1278 let _ = bigint_binary_mod(dest, op1, op2, n, mbedtls_sys_auto::mpi_mul_mpi);
1279}
1280
1281#[unsafe(no_mangle)]
1288pub extern "C" fn TEE_BigIntSquareMod(
1289 dest: *mut TEE_BigInt,
1290 op: *const TEE_BigInt,
1291 n: *const TEE_BigInt,
1292) {
1293 TEE_BigIntMulMod(dest, op, op, n);
1295}
1296
1297#[unsafe(no_mangle)]
1304pub extern "C" fn TEE_BigIntInvMod(
1305 dest: *mut TEE_BigInt,
1306 op: *const TEE_BigInt,
1307 n: *const TEE_BigInt,
1308) {
1309 if TEE_BigIntCmpS32(n, 2) < 0 || TEE_BigIntCmpS32(op, 0) == 0 {
1311 panic!("too small modulus or trying to invert zero");
1312 }
1313
1314 unsafe {
1315 let dst_hdr = dest as *mut BigintHdr;
1317 let alloc_size = (*dst_hdr).alloc_size as usize;
1318
1319 let mpi_n = match Mpi::from_teebigint(n) {
1321 Ok(mpi) => mpi,
1322 Err(_) => return, };
1324
1325 let mpi_op = if op == dest as *const TEE_BigInt {
1327 match Mpi::from_teebigint(op) {
1329 Ok(mpi) => mpi,
1330 Err(_) => return, }
1332 } else {
1333 match Mpi::from_teebigint(op) {
1335 Ok(mpi) => mpi,
1336 Err(_) => return, }
1338 };
1339
1340 let mut mpi_dest = match Mpi::new(0) {
1342 Ok(mpi) => mpi,
1343 Err(_) => return, };
1345
1346 let result =
1348 mbedtls_sys::mpi_inv_mod((&mut mpi_dest).into(), (&mpi_op).into(), (&mpi_n).into());
1349
1350 if result != 0 {
1351 return; }
1353
1354 let _ = mpi_dest.to_teebigint(dest, alloc_size);
1356 }
1357}
1358
1359fn tee_bigint_is_odd(src: *const TEE_BigInt) -> bool {
1367 TEE_BigIntGetBit(src, 0)
1369}
1370
1371fn tee_bigint_is_even(src: *const TEE_BigInt) -> bool {
1379 !tee_bigint_is_odd(src)
1380}
1381
1382#[unsafe(no_mangle)]
1394pub extern "C" fn TEE_BigIntExpMod(
1395 dest: *mut TEE_BigInt,
1396 op1: *const TEE_BigInt,
1397 op2: *const TEE_BigInt,
1398 n: *const TEE_BigInt,
1399 _context: *const TEE_BigIntFMMContext,
1400) -> TEE_Result {
1401 if TEE_BigIntCmpS32(n, 2) <= 0 {
1403 panic!("too small modulus");
1404 }
1405
1406 if tee_bigint_is_even(n) {
1408 return TEE_ERROR_OVERFLOW; }
1410
1411 unsafe {
1412 let dst_hdr = dest as *mut BigintHdr;
1414 let alloc_size = (*dst_hdr).alloc_size as usize;
1415
1416 let mpi_n = match Mpi::from_teebigint(n) {
1418 Ok(mpi) => mpi,
1419 Err(_) => return TEE_ERROR_OVERFLOW,
1420 };
1421
1422 let mpi_op1 = if op1 == dest as *const TEE_BigInt {
1424 match Mpi::from_teebigint(op1) {
1426 Ok(mpi) => mpi,
1427 Err(_) => return TEE_ERROR_OVERFLOW,
1428 }
1429 } else {
1430 match Mpi::from_teebigint(op1) {
1432 Ok(mpi) => mpi,
1433 Err(_) => return TEE_ERROR_OVERFLOW,
1434 }
1435 };
1436
1437 let mpi_op2 = if op2 == dest as *const TEE_BigInt {
1439 match Mpi::from_teebigint(op2) {
1441 Ok(mpi) => mpi,
1442 Err(_) => return TEE_ERROR_OVERFLOW,
1443 }
1444 } else if op2 == op1 {
1445 mpi_op1.clone()
1447 } else {
1448 match Mpi::from_teebigint(op2) {
1450 Ok(mpi) => mpi,
1451 Err(_) => return TEE_ERROR_OVERFLOW,
1452 }
1453 };
1454
1455 let mut mpi_dest = match Mpi::new(0) {
1457 Ok(mpi) => mpi,
1458 Err(_) => return TEE_ERROR_OVERFLOW,
1459 };
1460
1461 let result = mbedtls_sys::mpi_exp_mod(
1463 (&mut mpi_dest).into(),
1464 (&mpi_op1).into(),
1465 (&mpi_op2).into(),
1466 (&mpi_n).into(),
1467 core::ptr::null_mut(), );
1469
1470 if result != 0 {
1471 return TEE_ERROR_OVERFLOW;
1472 }
1473
1474 match mpi_dest.to_teebigint(dest, alloc_size) {
1476 Ok(()) => TEE_SUCCESS,
1477 Err(_) => TEE_ERROR_OVERFLOW,
1478 }
1479 }
1480}
1481
1482#[unsafe(no_mangle)]
1491pub extern "C" fn TEE_BigIntRelativePrime(op1: *const TEE_BigInt, op2: *const TEE_BigInt) -> bool {
1492 unsafe {
1493 let mpi_op1 = match Mpi::from_teebigint(op1) {
1495 Ok(mpi) => mpi,
1496 Err(_) => return false, };
1498
1499 let mpi_op2 = if op2 == op1 {
1501 mpi_op1.clone()
1503 } else {
1504 match Mpi::from_teebigint(op2) {
1505 Ok(mpi) => mpi,
1506 Err(_) => return false, }
1508 };
1509
1510 let mut gcd = match Mpi::new(0) {
1512 Ok(mpi) => mpi,
1513 Err(_) => return false, };
1515
1516 let result = mbedtls_sys::mpi_gcd((&mut gcd).into(), (&mpi_op1).into(), (&mpi_op2).into());
1518
1519 if result != 0 {
1520 return false; }
1522
1523 match Mpi::new(1) {
1526 Ok(one) => {
1527 match gcd.cmp(&one) {
1528 std::cmp::Ordering::Equal => true, _ => false, }
1531 }
1532 Err(_) => false, }
1534 }
1535}
1536
1537#[unsafe(no_mangle)]
1546pub extern "C" fn TEE_BigIntComputeExtendedGcd(
1547 gcd: *mut TEE_BigInt,
1548 u: *mut TEE_BigInt,
1549 v: *mut TEE_BigInt,
1550 op1: *const TEE_BigInt,
1551 op2: *const TEE_BigInt,
1552) {
1553 if gcd.is_null() || op1.is_null() || op2.is_null() {
1555 return;
1556 }
1557
1558 unsafe {
1559 let mpi_op1 = match Mpi::from_teebigint(op1) {
1561 Ok(mpi) => mpi,
1562 Err(_) => return,
1563 };
1564
1565 let mpi_op2 = if op2 == op1 {
1566 mpi_op1.clone()
1567 } else {
1568 match Mpi::from_teebigint(op2) {
1569 Ok(mpi) => mpi,
1570 Err(_) => return,
1571 }
1572 };
1573
1574 if u.is_null() && v.is_null() {
1576 let mut mpi_gcd = match Mpi::new(0) {
1577 Ok(mpi) => mpi,
1578 Err(_) => return,
1579 };
1580
1581 let result =
1582 mbedtls_sys::mpi_gcd((&mut mpi_gcd).into(), (&mpi_op1).into(), (&mpi_op2).into());
1583
1584 if result != 0 {
1585 return;
1586 }
1587
1588 let hdr = gcd as *mut BigintHdr;
1590 let alloc_size = (*hdr).alloc_size as usize;
1591 let _ = mpi_gcd.to_teebigint(gcd, alloc_size);
1592 return;
1593 }
1594
1595 let s1 = mpi_op1.sign();
1597 let s2 = mpi_op2.sign();
1598
1599 let abs_op1 = mpi_abs_value(&mpi_op1);
1601 let abs_op2 = mpi_abs_value(&mpi_op2);
1602
1603 let cmp = abs_op1.cmp(&abs_op2);
1604
1605 let (mpi_gcd, mpi_u, mpi_v) = match cmp {
1606 std::cmp::Ordering::Equal => {
1608 let gcd_result = abs_op1;
1610 let u_result = match Mpi::new(1) {
1611 Ok(mpi) => mpi,
1612 Err(_) => return,
1613 };
1614 let v_result = match Mpi::new(0) {
1615 Ok(mpi) => mpi,
1616 Err(_) => return,
1617 };
1618 (gcd_result, u_result, v_result)
1619 }
1620 std::cmp::Ordering::Greater => extended_gcd_algorithm(&abs_op1, &abs_op2),
1621 std::cmp::Ordering::Less => {
1622 let (gcd_result, v_result, u_result) = extended_gcd_algorithm(&abs_op2, &abs_op1);
1624 (gcd_result, u_result, v_result)
1625 }
1626 };
1627
1628 let final_mpi_u = if s1 == mbedtls::bignum::Sign::Negative {
1630 negate_mpi_safe(&mpi_u)
1631 } else {
1632 mpi_u
1633 };
1634
1635 let final_mpi_v = if s2 == mbedtls::bignum::Sign::Negative {
1636 negate_mpi_safe(&mpi_v)
1637 } else {
1638 mpi_v
1639 };
1640
1641 if !u.is_null() {
1643 let hdr = u as *mut BigintHdr;
1644 let alloc_size = (*hdr).alloc_size as usize;
1645 let _ = final_mpi_u.to_teebigint(u, alloc_size);
1646 }
1647
1648 if !v.is_null() {
1649 let hdr = v as *mut BigintHdr;
1650 let alloc_size = (*hdr).alloc_size as usize;
1651 let _ = final_mpi_v.to_teebigint(v, alloc_size);
1652 }
1653
1654 let hdr = gcd as *mut BigintHdr;
1655 let alloc_size = (*hdr).alloc_size as usize;
1656 let _ = mpi_gcd.to_teebigint(gcd, alloc_size);
1657 }
1658}
1659
1660fn mpi_abs_value(mpi: &Mpi) -> Mpi {
1662 let mut result = mpi.clone();
1663 unsafe {
1665 let handle: *mut mbedtls_sys::mpi = (&mut result).into();
1666 (*handle).s = 1;
1667 }
1668 result
1669}
1670
1671fn negate_mpi_safe(mpi: &Mpi) -> Mpi {
1673 let mut result = mpi.clone();
1674 unsafe {
1676 let handle: *mut mbedtls_sys::mpi = (&mut result).into();
1677 (*handle).s *= -1;
1678 }
1679 result
1680}
1681
1682fn extended_gcd_algorithm(x: &Mpi, y: &Mpi) -> (Mpi, Mpi, Mpi) {
1691 if let (Ok(x_binary), Ok(y_binary)) = (x.to_binary(), y.to_binary()) {
1693 if x_binary.iter().all(|&b| b == 0) || y_binary.iter().all(|&b| b == 0) {
1694 return (
1696 Mpi::new(0).unwrap_or_else(|_| Mpi::new(0).expect("Failed to create Mpi")),
1697 Mpi::new(0).unwrap_or_else(|_| Mpi::new(0).expect("Failed to create Mpi")),
1698 Mpi::new(0).unwrap_or_else(|_| Mpi::new(0).expect("Failed to create Mpi")),
1699 );
1700 }
1701 }
1702
1703 let mut u = x.clone();
1704 let mut v = y.clone();
1705
1706 let mut a = Mpi::new(1).expect("Failed to create Mpi");
1708 let mut b = Mpi::new(0).expect("Failed to create Mpi");
1709 let mut c = Mpi::new(0).expect("Failed to create Mpi");
1710 let mut d = Mpi::new(1).expect("Failed to create Mpi");
1711
1712 let mut k = 0;
1714 while mpi_is_even(&u) && mpi_is_even(&v) {
1715 k += 1;
1716 u = (&u >> 1).expect("Shift operation failed");
1717 v = (&v >> 1).expect("Shift operation failed");
1718 }
1719
1720 let mut x_copy = u.clone();
1721 let mut y_copy = v.clone();
1722
1723 while !is_mpi_zero(&x_copy) {
1725 while mpi_is_even(&x_copy) {
1726 x_copy = (&x_copy >> 1).expect("Shift operation failed");
1727 if mpi_is_odd(&a) || mpi_is_odd(&b) {
1730 a = add_mpi_safe(&a, &y_copy);
1731 b = sub_mpi_safe(&b, &u);
1732 }
1733
1734 a = (&a >> 1).expect("Shift operation failed");
1735 b = (&b >> 1).expect("Shift operation failed");
1736 }
1737
1738 while mpi_is_even(&y_copy) {
1739 y_copy = (&y_copy >> 1).expect("Shift operation failed");
1740
1741 if mpi_is_odd(&c) || mpi_is_odd(&d) {
1742 c = add_mpi_safe(&c, &y_copy);
1743 d = sub_mpi_safe(&d, &u);
1744 }
1745
1746 c = (&c >> 1).expect("Shift operation failed");
1747 d = (&d >> 1).expect("Shift operation failed");
1748 }
1749
1750 match x_copy.cmp(&y_copy) {
1751 std::cmp::Ordering::Greater | std::cmp::Ordering::Equal => {
1752 x_copy = sub_mpi_safe(&x_copy, &y_copy);
1753 a = sub_mpi_safe(&a, &c);
1754 b = sub_mpi_safe(&b, &d);
1755 }
1756 std::cmp::Ordering::Less => {
1757 y_copy = sub_mpi_safe(&y_copy, &x_copy);
1758 c = sub_mpi_safe(&c, &a);
1759 d = sub_mpi_safe(&d, &b);
1760 }
1761 }
1762 }
1763
1764 let gcd = (&y_copy << k).expect("Shift operation failed");
1766
1767 (gcd, c, d)
1768}
1769
1770fn add_mpi_safe(op1: &Mpi, op2: &Mpi) -> Mpi {
1772 let mut result = Mpi::new(0).expect("Failed to create Mpi");
1773 let ret = unsafe { mbedtls_sys::mpi_add_mpi((&mut result).into(), op1.into(), op2.into()) };
1774
1775 if ret == 0 {
1776 result
1777 } else {
1778 Mpi::new(0).expect("Failed to create Mpi")
1779 }
1780}
1781
1782fn sub_mpi_safe(op1: &Mpi, op2: &Mpi) -> Mpi {
1784 let mut result = Mpi::new(0).expect("Failed to create Mpi");
1785 let ret = unsafe { mbedtls_sys::mpi_sub_mpi((&mut result).into(), op1.into(), op2.into()) };
1786
1787 if ret == 0 {
1788 result
1789 } else {
1790 Mpi::new(0).expect("Failed to create Mpi")
1791 }
1792}
1793
1794fn is_mpi_zero(mpi: &Mpi) -> bool {
1796 match mpi.to_binary() {
1797 Ok(data) => data.iter().all(|&b| b == 0),
1798 Err(_) => true,
1799 }
1800}
1801
1802fn mpi_is_even(mpi: &Mpi) -> bool {
1804 match mpi.to_binary() {
1805 Ok(data) => {
1806 if data.is_empty() {
1807 true
1808 } else {
1809 (data[data.len() - 1] & 1) == 0
1810 }
1811 }
1812 Err(_) => true,
1813 }
1814}
1815
1816fn mpi_is_odd(mpi: &Mpi) -> bool {
1818 !mpi_is_even(mpi)
1819}
1820
1821#[unsafe(no_mangle)]
1830pub extern "C" fn TEE_BigIntIsProbablePrime(op: *const TEE_BigInt, confidenceLevel: u32) -> i32 {
1831 if op.is_null() {
1833 return 0;
1834 }
1835
1836 let mpi = match unsafe { Mpi::from_teebigint(op) } {
1838 Ok(mpi) => mpi,
1839 Err(_) => return 0,
1840 };
1841
1842 let rounds = confidenceLevel.max(80);
1844
1845 struct TeeRng;
1847
1848 impl RngCallback for TeeRng {
1849 unsafe extern "C" fn call(
1850 _user_data: *mut mbedtls_sys_auto::types::raw_types::c_void,
1851 data: *mut u8,
1852 len: usize,
1853 ) -> i32 {
1854 unsafe {
1857 for i in 0..len {
1858 *data.add(i) = (i % 256) as u8;
1859 }
1860 }
1861 0 }
1863
1864 fn data_ptr(&self) -> *mut mbedtls_sys_auto::types::raw_types::c_void {
1865 core::ptr::null_mut()
1866 }
1867 }
1868
1869 let mut rng = TeeRng;
1871 match mpi.is_probably_prime(rounds, &mut rng) {
1872 Ok(()) => 1, Err(_) => 0, }
1875}
1876
1877#[unsafe(no_mangle)]
1883pub extern "C" fn TEE_BigIntInitFMM(big_int_fmm: *mut TEE_BigIntFMM, len: usize) {
1884 TEE_BigIntInit(big_int_fmm, len);
1885}
1886
1887#[unsafe(no_mangle)]
1897pub extern "C" fn TEE_BigIntInitFMMContext1(
1898 context: *mut TEE_BigIntFMMContext,
1899 len: usize,
1900 modulus: *const TEE_BigInt,
1901) -> TEE_Result {
1902 let _ = context;
1904 let _ = len;
1905 let _ = modulus;
1906 TEE_SUCCESS
1907}
1908
1909#[unsafe(no_mangle)]
1917pub extern "C" fn TEE_BigIntFMMSizeInU32(modulus_size_in_bits: usize) -> usize {
1918 tee_big_int_size_in_u32(modulus_size_in_bits)
1920}
1921
1922#[unsafe(no_mangle)]
1930pub extern "C" fn TEE_BigIntFMMContextSizeInU32(modulus_size_in_bits: usize) -> usize {
1931 let _ = modulus_size_in_bits; 1
1934}
1935
1936#[unsafe(no_mangle)]
1944pub extern "C" fn TEE_BigIntConvertToFMM(
1945 dest: *mut TEE_BigIntFMM,
1946 src: *const TEE_BigInt,
1947 n: *const TEE_BigInt,
1948 context: *const TEE_BigIntFMMContext,
1949) {
1950 let _ = context; TEE_BigIntMod(dest as *mut TEE_BigInt, src, n);
1953}
1954
1955#[unsafe(no_mangle)]
1963pub extern "C" fn TEE_BigIntConvertFromFMM(
1964 dest: *mut TEE_BigInt,
1965 src: *const TEE_BigIntFMM,
1966 n: *const TEE_BigInt,
1967 context: *const TEE_BigIntFMMContext,
1968) {
1969 if dest.is_null() || src.is_null() {
1973 return;
1974 }
1975
1976 let mpi_src = match unsafe { Mpi::from_teebigint(src as *const TEE_BigInt) } {
1978 Ok(mpi) => mpi,
1979 Err(_) => return,
1980 };
1981
1982 let hdr = dest as *mut BigintHdr;
1984 let alloc_size = unsafe { (*hdr).alloc_size as usize };
1985
1986 let _ = unsafe { mpi_src.to_teebigint(dest, alloc_size) };
1988
1989 let _ = n;
1991 let _ = context;
1992}
1993
1994#[unsafe(no_mangle)]
2003pub extern "C" fn TEE_BigIntComputeFMM(
2004 dest: *mut TEE_BigIntFMM,
2005 op1: *const TEE_BigIntFMM,
2006 op2: *const TEE_BigIntFMM,
2007 n: *const TEE_BigInt,
2008 context: *const TEE_BigIntFMMContext,
2009) {
2010 if dest.is_null() || op1.is_null() || op2.is_null() || n.is_null() {
2012 return;
2013 }
2014
2015 let _ = context;
2017
2018 let mpi_op1 = match unsafe { Mpi::from_teebigint(op1 as *const TEE_BigInt) } {
2020 Ok(mpi) => mpi,
2021 Err(_) => return,
2022 };
2023
2024 let mpi_op2 = if op2 as *const TEE_BigInt == op1 as *const TEE_BigInt {
2025 mpi_op1.clone()
2027 } else {
2028 match unsafe { Mpi::from_teebigint(op2 as *const TEE_BigInt) } {
2029 Ok(mpi) => mpi,
2030 Err(_) => return,
2031 }
2032 };
2033
2034 let mpi_n = match unsafe { Mpi::from_teebigint(n) } {
2035 Ok(mpi) => mpi,
2036 Err(_) => return,
2037 };
2038
2039 let mut mpi_t = match Mpi::new(0) {
2041 Ok(mpi) => mpi,
2042 Err(_) => return,
2043 };
2044
2045 let mul_result = unsafe {
2047 mbedtls_sys::mpi_mul_mpi((&mut mpi_t).into(), (&mpi_op1).into(), (&mpi_op2).into())
2048 };
2049
2050 if mul_result != 0 {
2051 return;
2052 }
2053
2054 let dst_hdr = dest as *mut BigintHdr;
2056 let alloc_size = unsafe { (*dst_hdr).alloc_size as usize };
2057
2058 let mod_result = unsafe {
2060 mbedtls_sys::mpi_mod_mpi(
2061 (&mut mpi_t).into(), (&mpi_t).into(), (&mpi_n).into(), )
2065 };
2066
2067 if mod_result != 0 {
2068 return;
2069 }
2070
2071 let _ = unsafe { mpi_t.to_teebigint(dest as *mut TEE_BigInt, alloc_size) };
2073}