1use crate::{Error, Result};
19#[cfg(not(feature = "std"))]
20use alloc::vec::Vec;
21use core::{cmp::max, fmt};
22use optee_utee_sys as raw;
23
24pub type BigIntUnit = u32;
25pub type BigIntFMMUnit = u32;
26pub type BigIntFMMContextUnit = u32;
27
28pub struct BigInt(Vec<BigIntUnit>);
29
30impl BigInt {
31 pub fn data_ptr(&self) -> *const u32 {
32 self.0.as_ptr()
33 }
34
35 pub fn size_in_u32(size: u32) -> u32 {
37 size.div_ceil(32) + 2
38 }
39
40 pub fn new(bits: u32) -> Self {
41 let size: usize = Self::size_in_u32(bits) as usize;
42 let mut tmp_vec: Vec<BigIntUnit> = vec![0; size];
43 unsafe { raw::TEE_BigIntInit(tmp_vec.as_mut_ptr(), size) };
44 Self(tmp_vec)
45 }
46
47 pub fn convert_from_octet_string(&mut self, buffer: &[u8], sign: i32) -> Result<()> {
48 match unsafe {
49 raw::TEE_BigIntConvertFromOctetString(
50 self.0.as_mut_ptr(),
51 buffer.as_ptr(),
52 buffer.len(),
53 sign,
54 )
55 } {
56 raw::TEE_SUCCESS => Ok(()),
57 code => Err(Error::from_raw_error(code)),
58 }
59 }
60
61 pub fn convert_to_octet_string(&self) -> Result<Vec<u8>> {
62 let mut buffer_size: usize = (self.0.len() - 2) * 4;
63 let mut tmp_vec = vec![0u8; buffer_size];
64 match unsafe {
65 raw::TEE_BigIntConvertToOctetString(
66 tmp_vec.as_mut_ptr(),
67 &mut buffer_size,
68 self.data_ptr(),
69 )
70 } {
71 raw::TEE_SUCCESS => {
72 tmp_vec.truncate(buffer_size);
73 Ok(tmp_vec)
74 }
75 code => Err(Error::from_raw_error(code)),
76 }
77 }
78
79 pub fn convert_from_s32(&mut self, short_val: i32) {
80 unsafe { raw::TEE_BigIntConvertFromS32(self.0.as_mut_ptr(), short_val) };
81 }
82
83 pub fn convert_to_s32(&self) -> Result<i32> {
84 let mut short_val: i32 = 0;
85 match unsafe { raw::TEE_BigIntConvertToS32(&mut short_val as _, self.data_ptr()) } {
86 raw::TEE_SUCCESS => Ok(short_val),
87 code => Err(Error::from_raw_error(code)),
88 }
89 }
90
91 pub fn compare_big_int(&self, target: &Self) -> i32 {
95 unsafe { raw::TEE_BigIntCmp(self.data_ptr(), target.data_ptr()) }
96 }
97
98 pub fn compare_s32(&self, target: i32) -> i32 {
99 unsafe { raw::TEE_BigIntCmpS32(self.data_ptr(), target) }
100 }
101
102 pub fn shift_right(&mut self, op: &Self, bits: usize) {
103 unsafe { raw::TEE_BigIntShiftRight(self.0.as_mut_ptr(), op.data_ptr(), bits) };
106 }
107
108 pub fn get_bit(&self, bit_index: u32) -> bool {
109 unsafe { raw::TEE_BigIntGetBit(self.data_ptr(), bit_index) }
110 }
111
112 pub fn get_bit_count(&self) -> u32 {
113 unsafe { raw::TEE_BigIntGetBitCount(self.data_ptr()) }
114 }
115
116 pub fn add(op1: &Self, op2: &Self) -> Self {
117 let bits = max(Self::get_bit_count(op1), Self::get_bit_count(op2)) + 1;
118 let mut res = Self::new(bits);
119 unsafe { raw::TEE_BigIntAdd(res.0.as_mut_ptr(), op1.data_ptr(), op2.data_ptr()) };
120 res
121 }
122
123 pub fn sub(op1: &Self, op2: &Self) -> Self {
124 let bits = max(Self::get_bit_count(op1), Self::get_bit_count(op2)) + 1;
125 let mut res = Self::new(bits);
126 unsafe { raw::TEE_BigIntSub(res.0.as_mut_ptr(), op1.data_ptr(), op2.data_ptr()) };
127 res
128 }
129
130 pub fn neg(op: &Self) -> Self {
131 let mut res = Self::new(Self::get_bit_count(op));
132 unsafe { raw::TEE_BigIntNeg(res.0.as_mut_ptr(), op.data_ptr()) };
133 res
134 }
135
136 pub fn multiply(op1: &Self, op2: &Self) -> Self {
137 let bits = Self::get_bit_count(op1) + Self::get_bit_count(op2);
138 let mut res = Self::new(bits);
139 unsafe { raw::TEE_BigIntMul(res.0.as_mut_ptr(), op1.data_ptr(), op2.data_ptr()) };
140 res
141 }
142
143 pub fn square(op: &Self) -> Self {
144 let mut res = Self::new(2 * Self::get_bit_count(op));
145 unsafe { raw::TEE_BigIntSquare(res.0.as_mut_ptr(), op.data_ptr()) };
146 res
147 }
148
149 pub fn divide(op1: &Self, op2: &Self) -> (Self, Self) {
151 let q_bits = match op1.compare_big_int(op2) {
152 d if d >= 0 => max(1, Self::get_bit_count(op1) - Self::get_bit_count(op2)),
153 _ => 0,
154 };
155 let r_bits = Self::get_bit_count(op2);
156 let mut quotient = Self::new(q_bits);
157 let mut remainder = Self::new(r_bits);
158
159 unsafe {
160 raw::TEE_BigIntDiv(
161 quotient.0.as_mut_ptr(),
162 remainder.0.as_mut_ptr(),
163 op1.data_ptr(),
164 op2.data_ptr(),
165 )
166 };
167 (quotient, remainder)
168 }
169
170 pub fn module(op: &Self, n: &Self) -> Self {
171 let mut res = Self::new(Self::get_bit_count(n));
172 unsafe { raw::TEE_BigIntMod(res.0.as_mut_ptr(), op.data_ptr(), n.data_ptr()) };
173 res
174 }
175
176 pub fn add_mod(op1: &Self, op2: &Self, n: &Self) -> Self {
177 let mut res = Self::new(Self::get_bit_count(n));
178 unsafe {
179 raw::TEE_BigIntAddMod(
180 res.0.as_mut_ptr(),
181 op1.data_ptr(),
182 op2.data_ptr(),
183 n.data_ptr(),
184 )
185 };
186 res
187 }
188
189 pub fn sub_mod(op1: &Self, op2: &Self, n: &Self) -> Self {
190 let mut res = Self::new(Self::get_bit_count(n));
191 unsafe {
192 raw::TEE_BigIntSubMod(
193 res.0.as_mut_ptr(),
194 op1.data_ptr(),
195 op2.data_ptr(),
196 n.data_ptr(),
197 )
198 };
199 res
200 }
201
202 pub fn mul_mod(op1: &Self, op2: &Self, n: &Self) -> Self {
203 let mut res = Self::new(Self::get_bit_count(n));
204 unsafe {
205 raw::TEE_BigIntMulMod(
206 res.0.as_mut_ptr(),
207 op1.data_ptr(),
208 op2.data_ptr(),
209 n.data_ptr(),
210 )
211 };
212 res
213 }
214
215 pub fn square_mod(op: &Self, n: &Self) -> Self {
216 let mut res = Self::new(Self::get_bit_count(n));
217 unsafe { raw::TEE_BigIntSquareMod(res.0.as_mut_ptr(), op.data_ptr(), n.data_ptr()) };
218 res
219 }
220
221 pub fn inv_mod(op: &Self, n: &Self) -> Self {
222 let mut res = Self::new(Self::get_bit_count(n));
223 unsafe { raw::TEE_BigIntInvMod(res.0.as_mut_ptr(), op.data_ptr(), n.data_ptr()) };
224 res
225 }
226
227 pub fn relative_prime(op1: &Self, op2: &Self) -> bool {
228 unsafe { raw::TEE_BigIntRelativePrime(op1.data_ptr(), op2.data_ptr()) }
229 }
230
231 pub fn is_probable_prime(&self, confidence_level: u32) -> i32 {
236 unsafe { raw::TEE_BigIntIsProbablePrime(self.data_ptr(), confidence_level) }
237 }
238
239 pub fn convert_from_big_int_fmm(
240 &mut self,
241 src: &BigIntFMM,
242 n: &BigInt,
243 context: BigIntFMMContext,
244 ) {
245 unsafe {
246 raw::TEE_BigIntConvertToFMM(
247 self.0.as_mut_ptr(),
248 src.data_ptr(),
249 n.data_ptr(),
250 context.data_ptr(),
251 )
252 };
253 }
254}
255
256impl fmt::Display for BigInt {
257 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
258 write!(f, "{:x?}", self.0)
259 }
260}
261
262pub struct BigIntFMMContext(Vec<BigIntFMMContextUnit>);
263
264impl BigIntFMMContext {
265 pub fn data_ptr(&self) -> *const u32 {
266 self.0.as_ptr()
267 }
268
269 fn size_in_u32(size: usize) -> usize {
270 unsafe { raw::TEE_BigIntFMMContextSizeInU32(size) }
271 }
272
273 pub fn new(bits: u32, modulus: BigInt) -> Result<Self> {
275 let size: usize = Self::size_in_u32(bits as usize);
276 let mut tmp_vec: Vec<BigIntFMMContextUnit> = vec![0; size];
277 unsafe { raw::TEE_BigIntInitFMMContext(tmp_vec.as_mut_ptr(), size, modulus.data_ptr()) };
278 Ok(Self(tmp_vec))
279 }
280}
281
282pub struct BigIntFMM(Vec<BigIntFMMUnit>);
283
284impl BigIntFMM {
285 pub fn data_ptr(&self) -> *const u32 {
286 self.0.as_ptr()
287 }
288
289 fn size_in_u32(size: usize) -> usize {
290 unsafe { raw::TEE_BigIntFMMSizeInU32(size) }
291 }
292
293 pub fn new(bits: u32) -> Self {
294 let size: usize = Self::size_in_u32(bits as usize);
295 let mut tmp_vec: Vec<BigIntFMMUnit> = vec![0; size];
296 unsafe { raw::TEE_BigIntInitFMM(tmp_vec.as_mut_ptr(), size) };
297 Self(tmp_vec)
298 }
299
300 pub fn convert_from_big_int(&mut self, src: &BigInt, n: &BigInt, context: BigIntFMMContext) {
302 unsafe {
303 raw::TEE_BigIntConvertToFMM(
304 self.0.as_mut_ptr(),
305 src.data_ptr(),
306 n.data_ptr(),
307 context.data_ptr(),
308 )
309 };
310 }
311
312 pub fn compute_fmm(
314 &mut self,
315 op1: &BigIntFMM,
316 op2: &BigIntFMM,
317 n: &BigInt,
318 context: BigIntFMMContext,
319 ) {
320 unsafe {
321 raw::TEE_BigIntComputeFMM(
322 self.0.as_mut_ptr(),
323 op1.data_ptr(),
324 op2.data_ptr(),
325 n.data_ptr(),
326 context.data_ptr(),
327 )
328 };
329 }
330}
331