1 /* 2 * Copyright (C) 2022 Huawei Technologies Co., Ltd. 3 * Licensed under the Mulan PSL v2. 4 * You can use this software according to the terms and conditions of the Mulan PSL v2. 5 * You may obtain a copy of Mulan PSL v2 at: 6 * http://license.coscl.org.cn/MulanPSL2 7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR 8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR 9 * PURPOSE. 10 * See the Mulan PSL v2 for more details. 11 */ 12 13 #ifndef TEE_ARITH_API_H 14 #define TEE_ARITH_API_H 15 16 #include <tee_defines.h> 17 18 /* 19 * below definitions are defined by Global Platform 20 * for compatibility: 21 * don't make any change to the content below 22 */ 23 typedef uint32_t TEE_BigInt; 24 typedef uint32_t TEE_BigIntFMM; 25 typedef uint32_t TEE_BigIntFMMContext; 26 27 #define TEE_BigIntSizeInU32(n) ((((n) + 31) / 32) + 2) 28 29 /* 30 * returns the size of the array of uint32_t values 31 * 32 * @param modulusSizeInBits [IN] Size of modulus in bits 33 * 34 * @return Number of bytes needed to store a TEE_BigIntFMM given a modulus of length modulusSizeInBits 35 */ 36 size_t TEE_BigIntFMMSizeInU32(size_t modulusSizeInBits); 37 38 /* 39 * returns the size of the array of uint32_t values needed to represent a fast modular context 40 * 41 * @param modulusSizeInBits [IN] Size of modulus in bits 42 * 43 * @return Number of bytes needed to store a TEE_BigIntFMMContext given a modulus of length modulusSizeInBits 44 */ 45 size_t TEE_BigIntFMMContextSizeInU32(size_t modulusSizeInBits); 46 47 /* 48 * initializes bigInt 49 * 50 * @param bigInt[OUT] A pointer to the TEE_BigInt to be initialized 51 * @param len[IN] The size in uint32_t of the memory pointed to by bigInt 52 * 53 * @return void 54 */ 55 void TEE_BigIntInit(TEE_BigInt *bigInt, size_t len); 56 57 /* 58 * calculates the necessary prerequisites for the fast modular multiplication and stores them in a context. 59 * 60 * @param context[OUT] A pointer to the TEE_BigIntFMMContext to be initialized 61 * @param len[IN] The size in uint32_t of the memory pointed to by context 62 * @param modulus[IN] The modulus 63 * 64 * @return void 65 */ 66 void TEE_BigIntInitFMMContext(TEE_BigIntFMMContext *context, size_t len, const TEE_BigInt *modulus); 67 68 #if defined(API_LEVEL) && defined(API_LEVEL1_1_1) && (API_LEVEL >= API_LEVEL1_1_1) 69 70 /* 71 * calculates the necessary prerequisites for the fast modular multiplication and stores them in a context. 72 * 73 * @param context[OUT] A pointer to the TEE_BigIntFMMContext to be initialized 74 * @param len[IN] The size in uint32_t of the memory pointed to by context 75 * @param modulus[IN] The modulus 76 * 77 * @return #TEE_SUCCESS success 78 * @return other failed 79 */ 80 TEE_Result TEE_BigIntInitFMMContext1(TEE_BigIntFMMContext *context, size_t len, const TEE_BigInt *modulus); 81 #endif /* API_LEVEL */ 82 83 /* 84 * initializes bigIntFMM and sets its represented value to zero. 85 * 86 * @param context[IN] A pointer to the TEE_BigIntFMM to be initialized 87 * @param len[IN] The size in uint32_t of the memory pointed to by bigIntFMM 88 * 89 * @return void 90 */ 91 void TEE_BigIntInitFMM(TEE_BigIntFMM *bigIntFMM, size_t len); 92 93 /* 94 * converts a bufferLen byte octet string buffer into a TEE_BigInt format. 95 * 96 * @param dest [OUT] Pointer to a TEE_BigInt to hold the result 97 * @param buffer [IN] Pointer to the buffer containing the octet string representation of the integer 98 * @param bufferLen [IN] The length of *buffer in bytes 99 * @param sign [IN] The sign of dest is set to the sign of sign 100 * 101 * @return #TEE_SUCCESS support 102 * @return #TEE_ERROR_OVERFLOW If memory allocation for the dest is too small 103 */ 104 TEE_Result TEE_BigIntConvertFromOctetString(TEE_BigInt *dest, const uint8_t *buffer, size_t bufferLen, int32_t sign); 105 106 /* 107 * converts the absolute value of an integer in TEE_BigInt format into an octet string 108 * 109 * @param buffer [OUT] Output buffer where converted octet string representation of the integer is written 110 * @param bufferLen [IN] The length of *buffer in bytes 111 * @param bigInt [IN] Pointer to the integer that will be converted to an octet string 112 * 113 * @return #TEE_SUCCESS support 114 * @return #TEE_ERROR_SHORT_BUFFER If the output buffer is too small to contain the octet string 115 */ 116 TEE_Result TEE_BigIntConvertToOctetString(void *buffer, size_t *bufferLen, const TEE_BigInt *bigInt); 117 118 /* 119 * sets *dest to the value shortVal 120 * 121 * @param dest [OUT] Pointer to a TEE_BigInt to store the result 122 * @param shortVal [IN] Input value 123 * 124 * @return void 125 */ 126 void TEE_BigIntConvertFromS32(TEE_BigInt *dest, int32_t shortVal); 127 128 /* 129 * sets *dest to the value of src, including the sign of src. 130 * 131 * @param dest [OUT] Pointer to an int32_t to store the result 132 * @param src [IN] Pointer to the input value 133 * 134 * @return #TEE_SUCCESS support 135 * @return #TEE_ERROR_OVERFLOW If src does not fit within an int32_t 136 */ 137 TEE_Result TEE_BigIntConvertToS32(int32_t *dest, const TEE_BigInt *src); 138 139 /* 140 * checks whether op1>op2, op1==op2, or op1<op2 141 * 142 * @param op1 [IN] Pointer to the first operand 143 * @param op2 [IN] Pointer to the second operand 144 * 145 * @return 0 if op1==op2 146 * @return a positive number if op1>op2 147 */ 148 int32_t TEE_BigIntCmp(const TEE_BigInt *op1, const TEE_BigInt *op2); 149 150 /* 151 * checks whether op>shortVal, op==shortVal, or op<shortVal 152 * 153 * @param op [IN] Pointer to the first operand 154 * @param shortVal [IN] Pointer to the second operand 155 * 156 * @return 0 if op1==shortVal 157 * @return a positive number if op1>shortVal 158 */ 159 int32_t TEE_BigIntCmpS32(const TEE_BigInt *op, int32_t shortVal); 160 161 /* 162 * computes |dest| = |op| >> bits 163 * 164 * @param dest [OUT] Pointer to TEE_BigInt to hold the shifted result 165 * @param op [IN] Pointer to the operand to be shifted 166 * @param bits [IN] Number of bits to shift 167 * 168 * @return void 169 */ 170 void TEE_BigIntShiftRight(TEE_BigInt *dest, const TEE_BigInt *op, size_t bits); 171 172 /* 173 * returns the bitIndexth bit of the natural binary representation of |src| 174 * 175 * @param src [IN] Pointer to the integer 176 * @param bitIndex[IN] The offset of the bit to be read, starting at offset 0 for the least significant bit 177 * 178 * @return true The Boolean value of the bitIndexth bit in |src| is '1' 179 * @return false The Boolean value of the bitIndexth bit in |src| is '0' 180 */ 181 bool TEE_BigIntGetBit(const TEE_BigInt *src, uint32_t bitIndex); 182 183 /* 184 * returns the number of bits in the natural binary representation of |src|; that is, the magnitude of src 185 * 186 * @param src [IN] Pointer to the integer 187 * 188 * @return 0 src equals zero 189 * @return others The number of bits in the natural binary representation of |src|. 190 */ 191 uint32_t TEE_BigIntGetBitCount(const TEE_BigInt *src); 192 193 #if defined(API_LEVEL) && (API_LEVEL >= API_LEVEL1_2) 194 /* 195 * sets the bitIndexth bit of the natural binary representation of |op| to 1 or 0 196 * 197 * @param op [IN/OUT] Pointer to the integer 198 * @param bitIndex [IN] The offset of the bit to be set, starting at offset 0 for the least significant bit 199 * @param value [IN] The bit value to set where true represents a '1' and false represents a '0' 200 * 201 * @return #TEE_SUCCESS support 202 * @return #TEE_ERROR_OVERFLOW If the bitIndexth bit is larger than allocated bit length of op 203 */ 204 TEE_Result TEE_BigIntSetBit(TEE_BigInt *op, uint32_t bitIndex, bool value); 205 206 /* 207 * assigns the value of src to dest 208 * 209 * @param dest [OUT] Pointer to TEE_BigInt to be assigned 210 * @param src [IN] Pointer to the source operand 211 * 212 * @return #TEE_SUCCESS support 213 * @return #TEE_ERROR_OVERFLOW In case the dest operand cannot hold the value of src 214 */ 215 TEE_Result TEE_BigIntAssign(TEE_BigInt *dest, const TEE_BigInt *src); 216 217 /* 218 * assigns the value of |src| to dest 219 * 220 * @param dest [OUT] Pointer to TEE_BigInt to be assigned 221 * @param src [IN] Pointer to the source operand 222 * 223 * @return #TEE_SUCCESS support 224 * @return #TEE_ERROR_OVERFLOW In case the dest operand cannot hold the value of |src| 225 */ 226 TEE_Result TEE_BigIntAbs(TEE_BigInt *dest, const TEE_BigInt *src); 227 #endif /* API_LEVEL */ 228 229 /* 230 * computes dest = op1 + op2 231 * 232 * @param dest [OUT] Pointer to TEE_BigInt to store the result op1 + op2 233 * @param op1 [IN] Pointer to the first operand 234 * @param op2 [IN] Pointer to the second operand 235 * 236 * @return void 237 */ 238 void TEE_BigIntAdd(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2); 239 240 /* 241 * computes dest = op1 - op2 242 * 243 * @param dest [OUT] Pointer to TEE_BigInt to store the result op1 - op2 244 * @param op1 [IN] Pointer to the first operand 245 * @param op2 [IN] Pointer to the second operand 246 * 247 * @return void 248 */ 249 void TEE_BigIntSub(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2); 250 251 /* 252 * negates an operand: dest = -op 253 * 254 * @param dest [OUT] PPointer to TEE_BigInt to store the result -op 255 * @param op [IN] Pointer to the operand to be negated 256 * 257 * @return void 258 */ 259 void TEE_BigIntNeg(TEE_BigInt *dest, const TEE_BigInt *op); 260 261 /* 262 * computes dest = op1 * op2 263 * 264 * @param dest [OUT] Pointer to TEE_BigInt to store the result op1 * op2 265 * @param op1 [IN] Pointer to the first operand 266 * @param op2 [IN] Pointer to the second operand 267 * 268 * @return void 269 */ 270 void TEE_BigIntMul(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2); 271 272 /* 273 * computes dest = op * op 274 * 275 * @param dest [OUT] Pointer to TEE_BigInt to store the result op * op 276 * @param op [IN] Pointer to the operand to be squared 277 * 278 * @return void 279 */ 280 void TEE_BigIntSquare(TEE_BigInt *dest, const TEE_BigInt *op); 281 282 /* 283 * computes dest_r and dest_q such that op1 = dest_q * op2 + dest_r 284 * 285 * @param dest_q [OUT] Pointer to a TEE_BigInt to store the quotient 286 * @param dest_r [IN] Pointer to a TEE_BigInt to store the remainder 287 * @param op1 [OUT] Pointer to the first operand, the dividend 288 * @param op2 [IN] Pointer to the second operand, the divisor 289 * 290 * @return #TEE_SUCCESS operation success 291 * @return #TEE_ERROR_BAD_PARAMETERS If any of the parameters is NULL 292 */ 293 void TEE_BigIntDiv(TEE_BigInt *dest_q, TEE_BigInt *dest_r, const TEE_BigInt *op1, const TEE_BigInt *op2); 294 295 /* 296 * computes dest = op (mod n) such that 0 <= dest < n. 297 * 298 * @param dest [OUT] Pointer to TEE_BigInt to hold the result op (mod n) 299 * @param op [IN] Pointer to the operand to be reduced mod n 300 * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1. 301 * 302 * @return void 303 */ 304 void TEE_BigIntMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n); 305 306 /* 307 * computes dest = (op1 + op2) (mod n). 308 * 309 * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 + op2)(mod n) 310 * @param op1 [IN] Pointer to the first operand 311 * @param op2 [IN] Pointer to the second operand 312 * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1 313 * 314 * @return void 315 */ 316 void TEE_BigIntAddMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n); 317 318 /* 319 * computes dest = (op1 - op2) (mod n). 320 * 321 * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 - op2)(mod n) 322 * @param op1 [IN] Pointer to the first operand 323 * @param op2 [IN] Pointer to the second operand 324 * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1 325 * 326 * @return void 327 */ 328 void TEE_BigIntSubMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n); 329 330 /* 331 * computes dest = (op1 * op2) (mod n). 332 * 333 * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 * op2)(mod n) 334 * @param op1 [IN] Pointer to the first operand 335 * @param op2 [IN] Pointer to the second operand 336 * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1 337 * 338 * @return void 339 */ 340 void TEE_BigIntMulMod(TEE_BigInt *dest, const TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n); 341 342 /* 343 * computes dest = (op * op) (mod n). 344 * 345 * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op * op)(mod n) 346 * @param op1 [IN] Pointer to the operand 347 * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1 348 * 349 * @return void 350 */ 351 void TEE_BigIntSquareMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n); 352 353 /* 354 * computes dest such that dest * op = 1 (mod n). 355 * 356 * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op^-1)(mod n) 357 * @param op1 [IN] Pointer to the operand 358 * @param n [IN] Pointer to the modulus. Modulus SHALL be larger than 1 359 * 360 * @return void 361 */ 362 void TEE_BigIntInvMod(TEE_BigInt *dest, const TEE_BigInt *op, const TEE_BigInt *n); 363 364 /* 365 * determines whether gcd(op1, op2) == 1. 366 * 367 * @param op1 [IN] Pointer to the first operand 368 * @param op2 [IN] Pointer to the second operand 369 * 370 * @return true if gcd(op1, op2) == 1 371 * @return fast otherwise 372 */ 373 bool TEE_BigIntRelativePrime(const TEE_BigInt *op1, const TEE_BigInt *op2); 374 375 /* 376 * computes the greatest common divisor of the input parameters op1 and op2. 377 * 378 * @param gcd [OUT] Pointer to TEE_BigInt to hold the greatest common divisor of op1 and op2 379 * @param u [OUT] Pointer to TEE_BigInt to hold the first coefficient 380 * @param v [OUT] Pointer to TEE_BigInt to hold the second coefficient 381 * @param op1 [IN] Pointer to the first operand 382 * @param op2 [IN] Pointer to the second operand 383 * 384 * @return void 385 */ 386 void TEE_BigIntComputeExtendedGcd(TEE_BigInt *gcd, TEE_BigInt *u, TEE_BigInt *v, const TEE_BigInt *op1, 387 const TEE_BigInt *op2); 388 /* 389 * performs a probabilistic primality test on op 390 * 391 * @param op [IN] Candidate number that is tested for primality 392 * @param confidenceLevel [IN] The desired confidence level for a non-conclusive test 393 * 394 * @return 0 If op is a composite number 395 * @return 1 If op is guaranteed to be prime 396 * @return -1 If the test is non-conclusive but the probability that op is composite is less than 2^(-confidenceLevel) 397 */ 398 int32_t TEE_BigIntIsProbablePrime(const TEE_BigInt *op, uint32_t confidenceLevel); 399 400 /* 401 * converts src into a representation suitable for doing fast modular multiplicatio 402 * 403 * @param dest [OUT] Pointer to an initialized TEE_BigIntFMM memory area 404 * @param src [IN] Pointer to the TEE_BigInt to convert 405 * @param n [IN] Pointer to the modulus 406 * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1 407 * 408 * @return void 409 */ 410 void TEE_BigIntConvertToFMM(TEE_BigIntFMM *dest, const TEE_BigInt *src, const TEE_BigInt *n, 411 const TEE_BigIntFMMContext *context); 412 413 /* 414 * converts src in the fast modular multiplication representation back to a TEE_BigInt representation 415 * 416 * @param dest [OUT] Pointer to an initialized TEE_BigIntFMM memory area to hold the converted result 417 * @param src [IN] Pointer to a TEE_BigIntFMM holding the value in the fast modular multiplication representation 418 * @param n [IN] Pointer to the modulus 419 * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1 420 * 421 * @return void 422 */ 423 void TEE_BigIntConvertFromFMM(TEE_BigInt *dest, const TEE_BigIntFMM *src, const TEE_BigInt *n, 424 const TEE_BigIntFMMContext *context); 425 426 /* 427 * calculates dest = op1 * op2 in the fast modular multiplication representation 428 * 429 * @param dest [OUT] Pointer to TEE_BigIntFMM to hold the result op1 * op2 430 * @param op1 [IN] Pointer to the first operand 431 * @param op2 [IN] Pointer to the second operand 432 * @param n [IN] Pointer to the modulus 433 * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1 434 * 435 * @return void 436 */ 437 void TEE_BigIntComputeFMM(TEE_BigIntFMM *dest, const TEE_BigIntFMM *op1, const TEE_BigIntFMM *op2, const TEE_BigInt *n, 438 const TEE_BigIntFMMContext *context); 439 440 #if defined(API_LEVEL) && defined(API_LEVEL1_1_1) && (API_LEVEL >= API_LEVEL1_1_1) 441 /* 442 * computes dest = (op1 ^ op2) (mod n). 443 * 444 * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 ^ op2)(mod n) 445 * @param op1 [IN] Pointer to the first operand 446 * @param op2 [IN] Pointer to the second operand 447 * @param n [IN] Pointer to the modulus 448 * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1 or NULL 449 * 450 * @return #TEE_SUCCESS success 451 * @return #TEE_ERROR_NOT_SUPPORTED If the value of n is not supported 452 */ 453 TEE_Result TEE_BigIntExpMod(TEE_BigInt *des, TEE_BigInt *op1, const TEE_BigInt *op2, const TEE_BigInt *n, 454 TEE_BigIntFMMContext *context); 455 #endif /* API_LEVEL */ 456 457 /* 458 * check whether n exists to make dest = (op1 ^ op2) (mod n). 459 * 460 * @param dest [OUT] Pointer to TEE_BigInt to hold the result (op1 ^ op2)(mod n) 461 * @param op1 [IN] Pointer to the first operand 462 * @param op2 [IN] Pointer to the second operand 463 * @param n [IN] Pointer to the modulus 464 * @param context [IN] Pointer to a context previously initialized using TEE_BigIntInitFMMContext1 or NULL 465 * 466 * @return true If the value of n is supported 467 * @return false If the value of n is not supported 468 */ 469 bool EXT_TEE_BigIntExpMod(TEE_BigInt *out, TEE_BigInt *in, const TEE_BigInt *exp, const TEE_BigInt *n); 470 #endif 471