1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements.  See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership.  The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License.  You may obtain a copy of the License at
8 //
9 //   http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied.  See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17 
18 use crate::{Error, Result};
19 use optee_utee_sys as raw;
20 use std::{cmp::max, fmt};
21 
22 pub type BigIntUnit = u32;
23 pub type BigIntFMMUnit = u32;
24 pub type BigIntFMMContextUnit = u32;
25 
26 pub struct BigInt(Vec<BigIntUnit>);
27 
28 impl BigInt {
data_ptr(&self) -> *const u3229     pub fn data_ptr(&self) -> *const u32 {
30         self.0.as_ptr()
31     }
32 
33     // size represents BigInt bits
size_in_u32(size: u32) -> u3234     pub fn size_in_u32(size: u32) -> u32 {
35         return ((size + 31) / 32) + 2;
36     }
37 
new(bits: u32) -> Self38     pub fn new(bits: u32) -> Self {
39         let size: usize = Self::size_in_u32(bits) as usize;
40         let mut tmp_vec: Vec<BigIntUnit> = vec![0; size];
41         unsafe { raw::TEE_BigIntInit(tmp_vec.as_mut_ptr(), size as u32) };
42         Self(tmp_vec)
43     }
44 
convert_from_octet_string(&mut self, buffer: &[u8], sign: i32) -> Result<()>45     pub fn convert_from_octet_string(&mut self, buffer: &[u8], sign: i32) -> Result<()> {
46         match unsafe {
47             raw::TEE_BigIntConvertFromOctetString(
48                 self.0.as_mut_ptr(),
49                 buffer.as_ptr(),
50                 buffer.len() as u32,
51                 sign,
52             )
53         } {
54             raw::TEE_SUCCESS => Ok(()),
55             code => Err(Error::from_raw_error(code)),
56         }
57     }
58 
convert_to_octet_string(&self) -> Result<Vec<u8>>59     pub fn convert_to_octet_string(&self) -> Result<Vec<u8>> {
60         let mut buffer_size: u32 = (self.0.len() as u32 - 2) * 4;
61         let mut tmp_vec = vec![0u8; buffer_size as usize];
62         match unsafe {
63             raw::TEE_BigIntConvertToOctetString(
64                 tmp_vec.as_mut_ptr(),
65                 &mut buffer_size as _,
66                 self.data_ptr(),
67             )
68         } {
69             raw::TEE_SUCCESS => {
70                 tmp_vec.truncate(buffer_size as usize);
71                 return Ok(tmp_vec);
72             }
73             code => Err(Error::from_raw_error(code)),
74         }
75     }
76 
convert_from_s32(&mut self, short_val: i32)77     pub fn convert_from_s32(&mut self, short_val: i32) {
78         unsafe { raw::TEE_BigIntConvertFromS32(self.0.as_mut_ptr(), short_val) };
79     }
80 
convert_to_s32(&self) -> Result<i32>81     pub fn convert_to_s32(&self) -> Result<i32> {
82         let mut short_val: i32 = 0;
83         match unsafe { raw::TEE_BigIntConvertToS32(&mut short_val as _, self.data_ptr()) } {
84             raw::TEE_SUCCESS => Ok(short_val),
85             code => Err(Error::from_raw_error(code)),
86         }
87     }
88 
89     /* return negative number if self < target,
90     0 if self == target
91     positive number if self > target*/
compare_big_int(&self, target: &Self) -> i3292     pub fn compare_big_int(&self, target: &Self) -> i32 {
93         unsafe { raw::TEE_BigIntCmp(self.data_ptr(), target.data_ptr()) }
94     }
95 
compare_s32(&self, target: i32) -> i3296     pub fn compare_s32(&self, target: i32) -> i32 {
97         unsafe { raw::TEE_BigIntCmpS32(self.data_ptr(), target) }
98     }
99 
shift_right(&mut self, op: &Self, bits: usize)100     pub fn shift_right(&mut self, op: &Self, bits: usize) {
101         // Should return a BigInt, while its size is based on the abs function which is missed
102         // right now
103         unsafe { raw::TEE_BigIntShiftRight(self.0.as_mut_ptr(), op.data_ptr(), bits) };
104     }
105 
get_bit(&self, bit_index: u32) -> bool106     pub fn get_bit(&self, bit_index: u32) -> bool {
107         unsafe { raw::TEE_BigIntGetBit(self.data_ptr(), bit_index) }
108     }
109 
get_bit_count(&self) -> u32110     pub fn get_bit_count(&self) -> u32 {
111         unsafe { raw::TEE_BigIntGetBitCount(self.data_ptr()) }
112     }
113 
add(op1: &Self, op2: &Self) -> Self114     pub fn add(op1: &Self, op2: &Self) -> Self {
115         let bits = max(Self::get_bit_count(op1), Self::get_bit_count(op2)) + 1;
116         let mut res = Self::new(bits);
117         unsafe { raw::TEE_BigIntAdd(res.0.as_mut_ptr(), op1.data_ptr(), op2.data_ptr()) };
118         res
119     }
120 
sub(op1: &Self, op2: &Self) -> Self121     pub fn sub(op1: &Self, op2: &Self) -> Self {
122         let bits = max(Self::get_bit_count(op1), Self::get_bit_count(op2)) + 1;
123         let mut res = Self::new(bits);
124         unsafe { raw::TEE_BigIntSub(res.0.as_mut_ptr(), op1.data_ptr(), op2.data_ptr()) };
125         res
126     }
127 
neg(op: &Self) -> Self128     pub fn neg(op: &Self) -> Self {
129         let mut res = Self::new(Self::get_bit_count(op));
130         unsafe { raw::TEE_BigIntNeg(res.0.as_mut_ptr(), op.data_ptr()) };
131         res
132     }
133 
multiply(op1: &Self, op2: &Self) -> Self134     pub fn multiply(op1: &Self, op2: &Self) -> Self {
135         let bits = Self::get_bit_count(op1) + Self::get_bit_count(op2);
136         let mut res = Self::new(bits);
137         unsafe { raw::TEE_BigIntMul(res.0.as_mut_ptr(), op1.data_ptr(), op2.data_ptr()) };
138         res
139     }
140 
square(op: &Self) -> Self141     pub fn square(op: &Self) -> Self {
142         let mut res = Self::new(2 * Self::get_bit_count(op));
143         unsafe { raw::TEE_BigIntSquare(res.0.as_mut_ptr(), op.data_ptr()) };
144         res
145     }
146 
147     // document defines wrong size for result quotient
divide(op1: &Self, op2: &Self) -> (Self, Self)148     pub fn divide(op1: &Self, op2: &Self) -> (Self, Self) {
149         let q_bits = match op1.compare_big_int(op2) {
150             d if d >= 0 => max(1, Self::get_bit_count(op1) - Self::get_bit_count(op2)),
151             _ => 0,
152         };
153         let r_bits = Self::get_bit_count(op2);
154         let mut quotient = Self::new(q_bits);
155         let mut remainder = Self::new(r_bits);
156 
157         unsafe {
158             raw::TEE_BigIntDiv(
159                 quotient.0.as_mut_ptr(),
160                 remainder.0.as_mut_ptr(),
161                 op1.data_ptr(),
162                 op2.data_ptr(),
163             )
164         };
165         (quotient, remainder)
166     }
167 
module(op: &Self, n: &Self) -> Self168     pub fn module(op: &Self, n: &Self) -> Self {
169         let mut res = Self::new(Self::get_bit_count(n));
170         unsafe { raw::TEE_BigIntMod(res.0.as_mut_ptr(), op.data_ptr(), n.data_ptr()) };
171         res
172     }
173 
add_mod(op1: &Self, op2: &Self, n: &Self) -> Self174     pub fn add_mod(op1: &Self, op2: &Self, n: &Self) -> Self {
175         let mut res = Self::new(Self::get_bit_count(n));
176         unsafe {
177             raw::TEE_BigIntAddMod(
178                 res.0.as_mut_ptr(),
179                 op1.data_ptr(),
180                 op2.data_ptr(),
181                 n.data_ptr(),
182             )
183         };
184         res
185     }
186 
sub_mod(op1: &Self, op2: &Self, n: &Self) -> Self187     pub fn sub_mod(op1: &Self, op2: &Self, n: &Self) -> Self {
188         let mut res = Self::new(Self::get_bit_count(n));
189         unsafe {
190             raw::TEE_BigIntSubMod(
191                 res.0.as_mut_ptr(),
192                 op1.data_ptr(),
193                 op2.data_ptr(),
194                 n.data_ptr(),
195             )
196         };
197         res
198     }
199 
mul_mod(op1: &Self, op2: &Self, n: &Self) -> Self200     pub fn mul_mod(op1: &Self, op2: &Self, n: &Self) -> Self {
201         let mut res = Self::new(Self::get_bit_count(n));
202         unsafe {
203             raw::TEE_BigIntMulMod(
204                 res.0.as_mut_ptr(),
205                 op1.data_ptr(),
206                 op2.data_ptr(),
207                 n.data_ptr(),
208             )
209         };
210         res
211     }
212 
square_mod(op: &Self, n: &Self) -> Self213     pub fn square_mod(op: &Self, n: &Self) -> Self {
214         let mut res = Self::new(Self::get_bit_count(n));
215         unsafe { raw::TEE_BigIntSquareMod(res.0.as_mut_ptr(), op.data_ptr(), n.data_ptr()) };
216         res
217     }
218 
inv_mod(op: &Self, n: &Self) -> Self219     pub fn inv_mod(op: &Self, n: &Self) -> Self {
220         let mut res = Self::new(Self::get_bit_count(n));
221         unsafe { raw::TEE_BigIntInvMod(res.0.as_mut_ptr(), op.data_ptr(), n.data_ptr()) };
222         res
223     }
224 
relative_prime(op1: &Self, op2: &Self) -> bool225     pub fn relative_prime(op1: &Self, op2: &Self) -> bool {
226         unsafe { raw::TEE_BigIntRelativePrime(op1.data_ptr(), op2.data_ptr()) }
227     }
228 
229     /* pub fn compute_extended_gcd(op1: &Self, op2: &Self) -> (Self, Self, Self)
230      * This function is implemented in OP-TEE, while the output size needs to be calculated based
231      * on the missing function TEE_BigIntAbs, so we do not port it yet.*/
232 
is_probable_prime(&self, confidence_level: u32) -> i32233     pub fn is_probable_prime(&self, confidence_level: u32) -> i32 {
234         unsafe { raw::TEE_BigIntIsProbablePrime(self.data_ptr(), confidence_level) }
235     }
236 
convert_from_big_int_fmm( &mut self, src: &BigIntFMM, n: &BigInt, context: BigIntFMMContext, )237     pub fn convert_from_big_int_fmm(
238         &mut self,
239         src: &BigIntFMM,
240         n: &BigInt,
241         context: BigIntFMMContext,
242     ) {
243         unsafe {
244             raw::TEE_BigIntConvertToFMM(
245                 self.0.as_mut_ptr(),
246                 src.data_ptr(),
247                 n.data_ptr(),
248                 context.data_ptr(),
249             )
250         };
251     }
252 }
253 
254 impl fmt::Display for BigInt {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result255     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
256         write!(f, "{:x?}", self.0)
257     }
258 }
259 
260 pub struct BigIntFMMContext(Vec<BigIntFMMContextUnit>);
261 
262 impl BigIntFMMContext {
data_ptr(&self) -> *const u32263     pub fn data_ptr(&self) -> *const u32 {
264         self.0.as_ptr()
265     }
266 
size_in_u32(size: u32) -> u32267     fn size_in_u32(size: u32) -> u32 {
268         unsafe { raw::TEE_BigIntFMMContextSizeInU32(size) }
269     }
270 
271     // Globalplatform define FMMContext1 here while OP-TEE does not update yet
new(bits: u32, modulus: BigInt) -> Result<Self>272     pub fn new(bits: u32, modulus: BigInt) -> Result<Self> {
273         let size: usize = Self::size_in_u32(bits) as usize;
274         let mut tmp_vec: Vec<BigIntFMMContextUnit> = vec![0; size];
275         unsafe {
276             raw::TEE_BigIntInitFMMContext(tmp_vec.as_mut_ptr(), size as u32, modulus.data_ptr())
277         };
278         Ok(Self(tmp_vec))
279     }
280 }
281 
282 pub struct BigIntFMM(Vec<BigIntFMMUnit>);
283 
284 impl BigIntFMM {
data_ptr(&self) -> *const u32285     pub fn data_ptr(&self) -> *const u32 {
286         self.0.as_ptr()
287     }
288 
size_in_u32(size: u32) -> u32289     fn size_in_u32(size: u32) -> u32 {
290         unsafe { raw::TEE_BigIntFMMSizeInU32(size) }
291     }
292 
new(bits: u32) -> Self293     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 as u32) };
297         Self(tmp_vec)
298     }
299 
300     //Has to be initialized first
convert_from_big_int(&mut self, src: &BigInt, n: &BigInt, context: BigIntFMMContext)301     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     //Has to be initialized first
compute_fmm( &mut self, op1: &BigIntFMM, op2: &BigIntFMM, n: &BigInt, context: BigIntFMMContext, )313     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 //OP-TEE does not implement function:
332 //TEE_BigIntSetBit
333 //TEE_BigIntAssign
334 //TEE_BigIntAbs
335 //TEE_BigIntExpMod
336