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